模块是实现某个功能的代码集合
函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。
模块分为三种:
内置标准模块(标准库)
第三方模块(开源模块)
自定义模块
1. 自定义模块
# 单模块,且在同一目录下,建议用 import # 定义一个模块文件名字为common.py,在当前目录 def f2(): print("F2") #导入模块 import common common.f2() # 自定义模块在其他文件夹下,例如 lib/common2.py # 方式一: import lib.common2 # 方式二:推荐使用这种方式 from lib import common2 as lib_common2 # 从lib目录导入common2模块,命名为lib_common2 lib_common2.f2()
导入模块的依据
import sys print(sys.path) --> [‘E:\\project\\day5‘, ‘E:\\project\\day5‘, ‘E:\\Python35\\python35.zip‘, ‘E:\\Python35\\DLLs‘, ‘E:\\Python35\\lib‘, ‘E:\\Python35‘, ‘E:\\Python35\\lib\\site-packages‘]
2、第三方模块的安装
有两种方式,一种是通过yum/pip/atp-get等安装;另一种是通过源码编译安装。安装成功后,模块会自动安装到 sys.path 中的某个目录中。
requests第三方模块
import requests ret = requests.get("http://www.baidu.com") print(ret) <Response [200]>
3、标准模块
不用安装,安装好python的环境后就可以使用,导入方式与之前相同。
(1)json & pickle 模块
这两个是用于序列化的两个模块
json与pickle的区别
- json: 更适合跨语言的内容交互,使用的是字符串,只支持基本的python数据类型
- pickle: 仅适用于python, 支持所有python类型的序列化
这两个模块都提供了四个功能:loads、load、dumps、dump
- loads 在内存中,将字符串格式的变量转换为对应python数据类型
- dumps 与loads相反,将python数据类型转换为字符串,赋值给变量
- load 读取文件中内容,并转换为python的数据类型
- dump 把内容写入到文件
# pikle import pickle li = [11,22,33, ] # 内存中转换 s = pickle.dumps(li) print(s, type(s)) ret = pickle.loads(s) print(ret) # 文件内读写 pickle.dump(li, open("db", "wb")) # 只能是字节类型的读写 res = pickle.load(open("db", "rb")) print(res, type(res)) import json # 字典数据类型转换成字典样式的字符串 dic = {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, } res = json.dumps(dic) print(res, type(res)) # 字典样式的字符串字典转换成字典数据类型 s1 = ‘{"k2": "v2", "k1": "v1"}‘ d1 = json.loads(s1) print(d1, type(d1))
练习:
import requests import json r = requests.get("http://wthrcdn.etouch.cn/weather_mini?city=北京") r.encoding = "utf-8" s1 = r.text # 读取网页访问结果的字符串到内存 res = json.loads(s1) # 将字符串转换成python的字典类型 print(type(res), type(r)) 结果: <class ‘dict‘> <class ‘requests.models.Response‘> json.dump(s1, open("msg.data", "w")) # 将s1写入到文件 res = json.load(open("msg.data", "r")) # 将文件内容字符串读取到内存,并转换成相应的python字典或列表等数据类型 print(res, type(res))
(2)time & datetime 模块
time
时间相关的操作,时间有三种表示方式:
时间戳 1970年1月1日之后的秒,即:time.time()
格式化的字符串 2014-11-11 11:11, 即:time.strftime(‘%Y-%m-%d‘)
结构化时间 元组包含了:年、日、星期等... time.struct_time 即:time.localtime()
# time() print(time.time()) 结果: 1465536842.780465 # gmtime() # 返回结构化方式的时间,元组形式,格林尼治时间,可传递时间戳参数 print(time.gmtime(time.time())) 结果: time.struct_time(tm_year=2016, tm_mon=6, tm_mday=10, tm_hour=5, tm_min=44, tm_sec=34, tm_wday=4, tm_yday=162, tm_isdst=0) # localtime() # 返回本地时间,结构化的方式,可传递时间戳参数 print(time.localtime()) 结果: time.struct_time(tm_year=2016, tm_mon=6, tm_mday=10, tm_hour=13, tm_min=46, tm_sec=28, tm_wday=4, tm_yday=162, tm_isdst=0) # strptime() # 将字符串转化为日期格式 print(time.strptime(‘1986-10-31‘, ‘%Y-%m-%d‘)) 结果: time.struct_time(tm_year=1986, tm_mon=10, tm_mday=31, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=304, tm_isdst=-1) # strftime() # 以指定方式输出当前时间,字符串形式 print(time.strftime(‘%Y-%m-%d %H:%M:%S‘)) 结果: 2016-06-10 13:56:08 # asctime() # 结构化格式转换为可读性好的格式 print(time.asctime()) print(time.asctime(time.localtime())) # 可以传递p_tuple参数 # ctime() 默认当前时间,可以传递时间戳参数 print(time.ctime(time.time()))
datetime 模块,通过time模块中的方法扩展,使用起来更方便
import datetime print(datetime.date.today()) # 输出格式2016-06-10 # 2016-06-10 将时间戳转成日期格式,可以通过加减秒数来改变输出的书时间 print(datetime.date.fromtimestamp(time.time() - 864400)) current_time = datetime.datetime.now() # 当前时间 print(current_time) # 输出2016-06-10 16:11:56.832662 print(current_time.timetuple()) # 返回struct_time格式 # datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]]) print(current_time.replace(1986, 10, 31)) # 输出1986-10-31,时间使用当前时间,但指定的值(年、月、日)将被替换 str_to_date = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") # 将字符串转换成日期格式 new_date = datetime.datetime.now() + datetime.timedelta(days=10) # 比现在加10天 new_date = datetime.datetime.now() + datetime.timedelta(days=-10) # 比现在减10天 new_date = datetime.datetime.now() + datetime.timedelta(hours=-10) # 比现在减10小时 new_date = datetime.datetime.now() + datetime.timedelta(seconds=120) # 比现在+120s print(new_date)
(3)logging 模块
用于便捷记录日志且线程安全的模块
很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块 提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical() 5个级别。
示例:
import logging logging.warning("user [Pesen] attempted wrong password more than 3 times") logging.critical("host is down") 结果: WARNING:root:user [Pesen] attempted wrong password more than 3 times CRITICAL:root:host is down
日志级别:
Level | When it’s used |
---|---|
DEBUG |
Detailed information, typically of interest only when diagnosing problems. |
INFO |
Confirmation that things are working as expected. |
WARNING |
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR |
Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL |
A serious error, indicating that the program itself may be unable to continue running. |
权重:(只有大于当前日志等级的操作才会被记录)
CRITICAL
=
50
FATAL
=
CRITICAL
ERROR
=
40
WARNING
=
30
WARN
=
WARNING
INFO
=
20
DEBUG
=
10
NOTSET
=
0
# 把日志写到文件 logging.basicConfig(filename=‘./example.log‘, level=logging.INFO) logging.debug(‘DEBUG’) # 配置文件中设定的日志级别是INFO,比这个级别低的debug不会输出。 logging.info(‘Info‘) logging.warning(‘Warning‘) 结果: $ cat example.log INFO:root:Info WARNING:root:Warning # 日志格式中加上时间 >>> import logging >>> logging.basicConfig(format=‘%(asctime)s %(message)s‘, datefmt=‘%m/%d/%Y %I:%M:%S %p‘) >>> logging.warning(‘is when this event was logged.‘) 06/10/2016 04:42:21 PM is when this event was logged.
如果想要将日志在屏幕和文件都打印(或者在屏幕、多个文件中打印),可是用logging模块的几个组件来实现,介绍如下:
The logging library takes a modular approach and offers several categories of components: loggers, handlers, filters, and formatters.
-
- Loggers expose the interface that application code directly uses.
- Handlers send the log records (created by loggers) to the appropriate destination.
- Filters provide a finer grained facility for determining which log records to output.
- Formatters specify the layout of log records in the final output.
import logging #创建logger logger = logging.getLogger(‘TEST-LOG‘) # logger的名称 logger.setLevel(logging.DEBUG) # 日志级别,大于等于这个级别的才能输出到指定位置 # 创建屏幕终端输出的handler,并设定日志级别为DEBUG ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # 创建输出到文件的handler,并设定日志界别为WARNING fh = logging.FileHandler("access.log") fh.setLevel(logging.WARNING) # 创建 formatter formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘) # 把formatter的设置指定给handler ch.setFormatter(formatter) fh.setFormatter(formatter) # 把handler传递给logger logger.addHandler(ch) logger.addHandler(fh) # 将上面的配置应用到具体的日志输出 logger.debug(‘debug message‘) logger.info(‘info message‘) logger.warn(‘warn message‘) logger.error(‘error message‘) logger.critical(‘critical message‘) 结果: 屏幕输出: 2016-06-10 16:55:47,628 - TEST-LOG - DEBUG - debug message 2016-06-10 16:55:47,629 - TEST-LOG - INFO - info message 2016-06-10 16:55:47,629 - TEST-LOG - WARNING - warn message 2016-06-10 16:55:47,629 - TEST-LOG - ERROR - error message 2016-06-10 16:55:47,629 - TEST-LOG - CRITICAL - critical message 文件输出: 2016-06-10 16:55:47,629 - TEST-LOG - WARNING - warn message 2016-06-10 16:55:47,629 - TEST-LOG - ERROR - error message 2016-06-10 16:55:47,629 - TEST-LOG - CRITICAL - critical message