Python常用模块
-
时间模块(time)
和时间有关系的我们就要用到时间模块。在使用模块之前,应该首先导入这个模块。
# 常用方法 import time time.sleep(secs) # 使线程延迟指定的时间运行,时间单位为秒 time.time() # 获取当前时间戳
-
在Python表示时间的三种方式:
-
时间戳:通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
-
格式化时间:"2019-07-02"
-
结构化时间:struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
# Python中时间日期格式化符号 %y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-23) %I 12小时制小时数(01-12) %M 分钟数(00=59) %S 秒(00-59) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %Z 当前时区的名称 %% %号本身
import time # 时间戳 ret = time.time() print(ret) # 结构化时间 ret = time.localtime() print(ret) # 格式化时间 ret= time.strftime('%Y-%m-%d') print(ret)
小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;结构化时间则是用来操作时间的
-
-
几种格式之间的转换
import time # 1、时间戳 ——> 结构化时间 timestamp = time.time() struct_time = time.localtime(timestamp) # 2、结构化时间 ——> 格式化时间 format_time = time.strftime("%Y-%m-%d", struct_time) # 3、格式化时间 ——> 结构化时间 struct_time = time.strptime(format_time, "%Y-%m-%d") # 4、结构化时间 ——> 时间戳 stamptime = time.mktime(struct_time)
-
-
random模块
import random # 1、获取随机整数(闭区间) random.randint(3,5) # 2、获取随机整数(左闭右开) random.randrange(3, 5) # 3、获取随机0-1之内随机小数 random.random() # 4、获取指定范围内的随机小数 random.uniform(1, 3) # 5、随机选择一个并返回值 lst = [1, "dogfa", {"age": 18}, [1,2,3], ("哈哈",)] random.choice(lst) # 6、随机选择多个并返回值,返回个数取决于第二个参数 lst = [1, "dogfa", {"age": 18}, [1,2,3], ("哈哈",)] random.sample(lst, 2) # 7、打乱列表顺序 lst = [1, "dogfa", {"age": 18}, [1,2,3], ("哈哈",)] random.shuffle(lst)
-
sys模块
sys模块是与python解释器交互的一个接口
sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称
-
os模块
os模块是与操作系统交互的一个接口
os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.system("bash command") 运行shell命令,直接显示 os.popen("bash command).read() 运行shell命令,获取执行结果 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.path os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小 os.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为" ",Linux下为" " os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
注意:os.stat('path/filename') 获取文件/目录信息 的结构说明
stat 结构: st_mode: inode 保护模式 st_ino: inode 节点号。 st_dev: inode 驻留的设备。 st_nlink: inode 的链接数。 st_uid: 所有者的用户ID。 st_gid: 所有者的组ID。 st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。 st_atime: 上次访问的时间。 st_mtime: 最后一次修改的时间。 st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。
-
re模块
import re # 将所有满足正规则的值查询出来,并返回一个列表 ret = re.findall("a", "abcsasdasdafas") print(ret) # ['a', 'a', 'a', 'a', 'a'] # 将满足正则规则的第一个值查询出来,返回的是一个包含匹配结果的对象,可以通过obj.group()方法取出满足匹配结果的值,如果没有匹配到值,则返回None ret = re.search("a", "abcsasdasdafas") print(ret) # <_sre.SRE_Match object; span=(0, 1), match='a'> print(ret.group()) # a # 与search一样,只不过match只会从头开始匹配,相当于re.search("^a") ret = re.match("a", "abcsasdasdafas") print(ret) # <_sre.SRE_Match object; span=(0, 1), match='a'> print(ret.group()) # a # 对满足正则规则的值进行分割 ret = re.split("[ab]", "abcd") print(ret) # ['', '', 'cd'] # 将满足正则规则的值替换成W,参数1表示只替换3个 ret = re.sub("d", "W", "ad1a212af5a4s54a", 3) print(ret) # adWaWW2af5a4s54a # 和re.sub一样,只不过返回的值是一个元祖,里面包含替换的次数 ret = re.subn("d", "W", "ad1a212af5a4s54a", 3) print(ret) # ('adWaWW2af5a4s54a', 3) # 将正则表达式编译成一个正则表达式对象,再次解析正则表达式时将节省时间 obj = re.compile("d{3}") ret = obj.search("123das45asd879asd") print(ret.group()) # 123 # 返回值是一个迭代器,节省空间 ret = re.finditer("d", "123affdsfdsds5f4sdf") print([i.group() for i in ret]) # ['1', '2', '3', '5', '4']
注意:
-
findall的优先级查询
import re ret_lsit = re.findall("www.(baidu|2345).com", "www.baidu.com") print(ret_lsit) # ['baidu'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可 ret_lsit = re.findall("www.(?:baidu|2345).com", "www.baidu.com") print(ret_lsit) # ['www.baidu.com']
-
split的优先级查询
import re ret_lsit = re.split("d+", "dogfa38oldniu48djb27") print(ret_lsit) # ['dogfa', 'oldniu', 'djb', ''] ret_lsit = re.split("(d+)", "dogfa38oldniu48djb27") print(ret_lsit) # ['dogfa', '38', 'oldniu', '48', 'djb', '27', ''] #在匹配部分加上()之后所切出的结果是不同的, #没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项, #这个在某些需要保留匹配部分的使用过程是非常重要的。
re模块扩展
-
匹配标签
import re ret = re.search("<(?P<tags>w+)>.*</(?P=tags)>", "<h1>哈哈哈</h1>") print(ret.group()) # <h1>哈哈哈</h1> print(ret.group("tags")) # h1 #可以在分组中利用?<name>的形式给分组起名字 #获取的匹配结果可以直接用group('名字')拿到对应的值
-
匹配整数
import re ret = re.findall(r"-?d+.d+|(-?d+)", "1-2*(60+(-40.35/5)-(-4*3))") print(ret) # ['1', '-2', '60', '', '5', '-4', '3'] ret.remove("") print(ret) # ['1', '-2', '60', '5', '-4', '3']
-
数字匹配
1、 匹配一段文本中的每行的邮箱 http://blog.csdn.net/make164492212/article/details/51656638 2、 匹配一段文本中的每行的时间字符串,比如:‘1990-07-12’; 分别取出1年的12个月(^(0?[1-9]|1[0-2])$)、 一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$ 3、 匹配qq号。(腾讯QQ号从10000开始) [1,9][0,9]{4,} 4、 匹配一个浮点数。 ^(-?d+)(.d+)?$ 或者 -?d+.?d* 5、 匹配汉字。 ^[u4e00-u9fa5]{0,}$ 6、 匹配出所有整数
在线测试工具: http://tool.chinaz.com/regex/
-
-
序列化模块
-
什么是序列化?
将其它数据格式内容转换成一个字符串的过程就叫做序列化。
-
序列化的目的
- 以某种存储形式使自定义对象持久化
- 将对象从一个地方传递到另一个地方
- 使程序更具有维护性
-
Json
Json模块提供了四个功能:dumps、dump、loads、load
在Python中大部分类型数据不能转换成Json格式,只有少部分如:str,list,dict,int 类型可以转换成Json格式数据类型,且Json格式中字典的key值一定为字符串类型,在Json中字符串类型全都用双引号(" ")表示。
-
dumps 和 loads
import json dic = {"name":"dogfa", "age":18, "gender":"male", 1:2} json_dic = json.dumps(dic) # 序列化:将一个字典转换成一个字符串 print(json_dic) # {"name": "dogfa", "age": 18, "gender": "male", "1": 2} new_dic = json.loads(json_dic) # 反序列化:将Json格式数据转换成字典格式数据 print(new_dic) # {'name': 'dogfa', 'age': 18, 'gender': 'male', '1': 2} # 对比前后转换我们发现在转换成Json格式的时候,key全部转换成了字符串类型,而对这个结果再次转换回字典格式类型key表现的形式依旧是字符串类型。
-
dump 和 load
import json dic = {"name":"dogfa", "age":18, "gender":"male", 1:2} f = open("file/dog", mode="w", encoding="utf-8") json.dump(dic, f, ensure_ascii=False) # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close() # ensure_ascii:当它为True的时候,所有非ASCII码字符显示为uXXXX序列,只需在dump时将ensure_ascii设置为False即可,此时存入Json的中文即可正常显示。 f = open("file/dog", mode="r", encoding="utf-8") ret = json.load(f) # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 print(ret)
注意:可以dump多次数据到文件中,但是load不出来了。想dump多个数据进文件,用dumps。
import json dic = {"name":"dogfa", "age":18, "gender":"male", 1:2} lst = [1, 2, 3, 4] # 存值 f = open("file/dog", mode="w", encoding="utf-8") json_dic = json.dumps(dic, ensure_ascii=False) json_lst = json.dumps(lst, ensure_ascii=False) f.write(json_dic + " ") f.write(json_lst + " ") # 取值 f = open("file/dog", mode="r", encoding="utf-8") for line in f: print(json.loads(line))
-
-
pickle
pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load (不仅可以序列化字典,列表...可以把Python中基本上所有的数据类型序列化)
import pickle dic = {"name":"dogfa", "age":18, "gender":"male", 1:2} pic_dic = pickle.dumps(dic) print(pic_dic) # 一串bytes类型内容 new_dic = pickle.loads(pic_dic) print(new_dic) # {"name":"dogfa", "age":18, "gender":"male", 1:2} # pickle还可以存储对象 import time struct_time = time.localtime() print(type(struct_time), struct_time.tm_mday) # <class 'time.struct_time'> 3 f = open("file/dog", mode="wb") pickle.dump(struct_time, f) f = open("file/dog", mode="rb") new_struct_time = pickle.load(f) print(new_struct_time.tm_mday) # 3
总结:当序列化的内容是列表或者字典,推荐使用json模块。但如果出于某种原因你不得不序列化其他的数据类型,而未来你还会用Python对这个数据进行反序列化的话,那么就可以使用pickle。
-
-
hashliib模块
- 什么是hash?
hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值。
-
hash值得特点
-
只要传入的内容一样,得到的hash值必然一样
-
不能由hash值返解成内容
-
只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的
-
MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示
import hashlib md5_obj = hashlib.md5() md5_obj.update("dogfa".encode("utf-8")) ret = md5_obj.hexdigest() print(ret) # df4a1f9d8687dfaac078aa0a24a1ca29 md5_obj.update("sb".encode("utf-8")) print(md5_obj.hexdigest()) # 819bc0bd1c65f19111f95462e0560629 md5_obj = hashlib.md5() md5_obj.update("dogfasb".encode("utf-8")) ret = md5_obj.hexdigest() print(ret) # 819bc0bd1c65f19111f95462e0560629 # 注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样 # 但是update多次为校验大文件提供了可能。
由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”。
import hashlib md5_obj = hashlib.md5("我是盐".encode("utf-8")) md5_obj.update("dogfasb".encode("utf-8")) ret = md5_obj.hexdigest() print(ret) # 2c39693230a2e0ff4f98163e5b177a1c
-
logging模块(日志模块)
-
日志级别
CRITICAL = 50 #FATAL = CRITICAL ERROR = 40 WARNING = 30 #WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 #不设置
-
默认级别为warning,默认打印到终端
import logging logging.debug('调试debug') logging.info('消息info') logging.warning('警告warn') logging.error('错误error') logging.critical('严重critical') ''' WARNING:root:警告warn ERROR:root:错误error CRITICAL:root:严重critical '''
-
logger对象配置
import logging # 创建一个日志格式 format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger("sb") filehandle = logging.FileHandler("file/dog", encoding="utf-8") streamhandle = logging.StreamHandler() filehandle.setFormatter(format) streamhandle.setFormatter(format) logger.addHandler(filehandle) logger.addHandler(streamhandle) logger.setLevel(logging.DEBUG) logger.debug("我是debug") logger.info("我是info") logger.warning("我是warning") logger.error("我是error") logger.critical("我是critical")
-
配置参数
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有: filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。 format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 format参数中可能用到的格式化串: %(name)s Logger的名字 %(levelno)s 数字形式的日志级别 %(levelname)s 文本形式的日志级别 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 %(filename)s 调用日志输出函数的模块的文件名 %(module)s 调用日志输出函数的模块名 %(funcName)s 调用日志输出函数的函数名 %(lineno)d 调用日志输出函数的语句所在的代码行 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(thread)d 线程ID。可能没有 %(threadName)s 线程名。可能没有 %(process)d 进程ID。可能没有 %(message)s用户输出的消息
-
追踪错误提示信息
import traceback try: a except Exception as e: print(traceback.format_exc()) # Traceback (most recent call last): # File "E:/Python Code//日志文件.py", line 4, in <module> # a # NameError: name 'a' is not defined
-
-
collections模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
-
deque(双端队列)
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
from _collections import deque dq = deque(["a", "b", "c"]) dq.append("d") dq.appendleft("e") # 在队列的左端插入 print(dq) # deque(['e', 'a', 'b', 'c', 'd']) print(dq[2]) # 同样可以通过索引取值 # b
deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
# 对比列表和双端队列的插入速度 import time from collections import deque lst = list(range(1000000000)) # 列表插入数据时间 start_time = time.time() lst.insert(0, 1) end_time = time.time() speed_time = round(end_time - start_time, 2) print("lst_time:", speed_time) # 双端队列插入数据时间 dq = deque() dq.extend(lst) start_time = time.time() dq.insert(0, 1) end_time = time.time() speed_time = round(end_time - start_time) print("dq_time:", speed_time)
-
namedtuple
我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:
tu = (1, 2)
但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。
这时,namedtuple就派上了用场:
from collections import namedtuple Point = namedtuple('Point', ['x', 'y']) p = Point(1, 2) print(p.x) # 1 print(p.y) # 2
-
.........