11、Python标准模块
一、time模块
在python中,时间的表示有三种方式:时间戳表示,元组的表示和格式化表示,先来看一下这三种时间表示方法在python中的语法。
1、时间戳表示法:
import time print(time.time()) #时间戳表示 执行结果1517984732.4657302
要想获得系统的时间戳直接调用time模块的time函数就好了,那么这一坨1517984732.4657302是个什么玩意呢?不要方,我们来换算一下,我们将这个值换算成年也就是:1517984732.4657302/(60*60*24*365)约等于48年,用2018-1970=48。实际上,时间戳就是用当前时间减去1970然后再把这个单位换算成秒得来的。
2、元组表示法:
1 import time 2 print(time.gmtime(),time.localtime())#gmtime()为UTC时间,localtime()为本地时间 3 time_01 = time.localtime() 4 print(time_01.tm_year,time_01.tm_mon,time_01.tm_mday) #取出年月日
这2个方法都需要传递一个时间戳的参数,如果未传默认用系统的时间戳,返回的是一个元组,time.struct_time(tm_year=2018, tm_mon=2, tm_mday=7, tm_hour=14, tm_min=45, tm_sec=26, tm_wday=2, tm_yday=38, tm_isdst=0)。
3、格式化表示法:
很多时候我们希望时间能够展示成我们自己想要定义的格式,这时候就要用到格式化的表示方式。
1 import time 2 print(time.strftime("%Y-%m-%d %H:%M:%S")) #默认格式化系统当前时间 2018-02-07 14:57:50 3 print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(45454545))) #传入了一个tuple时间进行格式化 1971-06-11 10:15:45
学习了这三种时间的表示方法,我们用一个图来描述这三种表示法之间的相互转换。
二、datetime模块(待补充)
1 import datetime 2 print(datetime.datetime.now()) #系统当前日期 3 print(datetime.datetime.now()+datetime.timedelta(3,hours=10)) #后三天,10小时的时间
三、random模块
random模块用法如下:
1 import random 2 print(random.random()) #在区间[0,1)之间随机取值 3 help(random.choices) #help函数可以查看具体函数、模块等用法 4 print(random.randint(1,3)) #在区间[1,3]之间随机取整数 5 print(random.randrange(1,10,2)) #在区间[1,10,2)之间取随机整数 6 print(random.choice("123456azsxdsq"),random.choice([1,2,3,4,5])) #从字符串或列表中随机抽取元素 7 print(random.uniform(1,2))#在区间[1,2)之间的随机小数 8 print(random.choices("12ddsds",k=2)) #从字符串中随机返回2个字符 9 x = [1,2,3,4,5,6,7,8] 10 random.shuffle(x)#打乱顺序
利用random模块生成验证码:
1 def gernateVerCodeEx(size=4): 2 code = '' 3 for i in range(size): 4 current = random.randint(0,size-1) 5 if i == current: 6 code += str(random.randint(0,9)) 7 elif random.randint(0,size)%2 == 0: 8 code += chr(random.randint(65,90)) 9 else: 10 code += chr(random.randint(97,121)) 11 return code 12 print(gernateVerCodeEx(4))
四、OS模块
提供对操作系统进行调用的接口
1 import os 2 os.getcwd() #获取当前工作目录,即当前python脚本工作的目录路径 3 os.chdir("F:/") #改变当前脚本工作目录;相当于shell下cd 4 os.curdir #返回当前目录: ('.') 5 os.pardir #获取当前目录的父目录字符串名:('..') 6 os.makedirs('F:/a/b/c') #可生成多层递归目录 7 os.removedirs('test/a') #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 8 os.mkdir('dirname') #生成单级目录;相当于shell中mkdir dirname 9 os.rmdir('dirname') #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname 10 print(os.listdir("F:/python_learn")) #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 11 os.mkdir("test/a") 12 os.remove("test/a/11") #删除一个文件 13 os.rename("OS_learn.py","os_learn.py") #重命名文件/目录 14 os.stat('os_learn.py') #获取文件/目录信息 15 os.sep #输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" 16 os.linesep #输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" 17 os.pathsep #输出用于分割文件路径的字符串 18 os.name #输出字符串指示当前使用平台。win->'nt'; Linux->'posix' 19 os.system("ipconfig") #运行shell命令,直接显示 20 os.environ #获取系统环境变量 21 os.path.abspath("F:/python_learn") #返回path规范化的绝对路径 22 os.path.split("a/c/c") #将path分割成目录和文件名二元组返回 23 os.path.dirname("F:/python_learn") #返回path的目录。其实就是os.path.split(path)的第一个元素 24 os.path.basename("F:/python_learn") #返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 25 os.path.exists("F:/python_learn") #如果path存在,返回True;如果path不存在,返回False 26 os.path.isabs("/s") #如果path是绝对路径,返回True 27 os.path.isfile("F:/python_learn") # 如果path是一个存在的文件,返回True。否则返回False 28 os.path.isdir("F:/python_learn") #如果path是一个存在的目录,则返回True。否则返回False 29 os.path.join("F:\\","a","\\b") # #将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 30 os.path.getatime("F:/python_learn") #返回path所指向的文件或者目录的最后存取时间 31 os.path.getmtime("F:/python_learn") #返回path所指向的文件或者目录的最后修改时间
五、sys模块
1 # -*- coding:utf-8 -*- 2 import sys 3 sys.argv #命令行参数List,第一个元素是程序本身路径 4 sys.exit(0) #退出程序,正常退出时exit(0) 5 sys.version #获取Python解释程序的版本信息 6 sys.maxsize #最大的Int值 7 sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 8 sys.platform #返回操作系统平台名称 9 sys.stdout.write('please:') 10 val = sys.stdin.readline()[:-1] 11 print(val)
六、shutil模块
高级的 文件、文件夹、压缩包 处理模块
1 # -*- coding:utf-8 -*- 2 import shutil 3 with open("test_01","r") as fsrc,open("test_02","w") as fdst: 4 shutil.copyfileobj(fsrc, fdst) #将test_01的文件内容拷贝到test_02中 5 shutil.copyfile("test_01","test_02") #文件拷贝 6 shutil.copy("test_01","test_02") #拷贝文件和权限 7 shutil.copytree("F:/python_learn","F:/a") #递归拷贝 8 shutil.rmtree("F:/a") #递归删除目录 9 shutil.move("F:/test.txt","F:/software") #递归移动文件 10 shutil.make_archive("F:/a/python_learn_new", "zip", "F:/python_learn") # 压缩文件 11 shutil.unpack_archive("F:/a/python_learn_new.zip","F:/a","zip") #解压文件
七、shelve模块
helve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。
1 # -*- coding:utf-8 -*- 2 import shelve 3 info = {'name':'高文祥','age':18} 4 def getAddress(): 5 return "上海" 6 contract = {"address":getAddress,"QQ":"258469451","phone":"1585555555555"} 7 with shelve.open('shelve_test') as f:#打开一个文件 8 f["info"] = info 9 f["contract"] = contract #持久化数据 10 with shelve.open('shelve_test') as f: 11 info_01 = f["info"] 12 info_02 = f["contract"] #读取数据 13 print(info_01["name"], info_02["address"]())
讲到shelve,我们来学习一下2个序列号的方法json和pickle。
json序列化的代码如下:
1 info = {'name':'高文祥','age':18} 2 def getAddress(name): 3 return "上海"+name 4 contract = {"address":getAddress,"QQ":"258469451","phone":"1585555555555"} 5 import json 6 with open("json_01.txt","w",encoding="utf-8") as file: 7 json.dump(info,file) #序列化存入文件 json.dumps(info)只序列化不存入文件 8 json.dump(contract,file) #执行报错 json无法序列化函数TypeError: Object of type 'function' is not JSON serializable 9 10 with open("json_01.txt","r",encoding="utf-8") as file: 11 info_json = json.load(file) #反序列化 json.load() 只反序列化 不存入文件 12 print(info_json["name"])
pickle序列化代码如下:
import pickle info = {'name':'高文祥','age':18} def getAddress(name): return "上海"+name contract = {"address":getAddress,"QQ":"258469451","phone":"1585555555555"} stuNo = [1,2,3,4,5] with open("pickle_01.txt","wb") as file: pickle.dump(contract,file) #第1次dump pickle.dump(info, file)#第2次dump pickle.dump(stuNo,file)#第3次dump with open("pickle_01.txt","rb") as file: print(pickle.load(file))#执行结果{'address': <function getAddress at 0x0085F5D0>, 'QQ': '258469451', 'phone': '1585555555555'} print(pickle.load(file))#执行结果{'name': '高文祥', 'age': 18} print(pickle.load(file))#执行结果[1, 2, 3, 4, 5]
dumps和loads的使用:
import json,pickle info = {"name":"Helen","age":18} json_01 = json.dumps(info) json_02 = json.loads(json_01) print(type(json_01),type(json_02))
pickle_01 = pickle.dumps(info) pickle_02 = pickle.loads(pickle_01) print(type(pickle_01),type(pickle_02))
dump/load是将对象序列化(反序列化)到文件中(对象),dumps/loads则是将对象序列化(反序列化)成字符串(对象)
下面我们对shelve,json和pickle实现文件持久化功能作一个总结:
1、json只能序列化简单的数据类型,不能序列化函数,而shelve和pickle可以
2、shelve主要用将数据进行文件持久化时,非常好用
3、JSON只能处理基本数据类型。pickle能处理所有Python的数据类型。
4、JSON用于各种语言之间的字符转换。pickle用于Python程序对象的持久化或者Python程序间对象网络传输,但不同版本的Python序列化可能还有差异。
5、如果想把一个字符串转换为数据类型可以使用eval函数
八、configparser模块
用于生成和修改常见配置文档,下面就有configparser来生成一个配置文件,代码如下:
1 import configparser 2 config = configparser.ConfigParser() 3 config["DEFAULT"] = {'ServerAliveInterval': '45', 4 'Compression': 'yes', 5 'CompressionLevel': '9'} 6 config['bitbucket.org'] = {} 7 config['bitbucket.org']['User'] = 'hg' 8 config['topsecret.server.com'] = {} 9 topsecret = config['topsecret.server.com'] 10 topsecret['Host Port'] = '50022' # mutates the parser 11 topsecret['ForwardX11'] = 'no' # same here 12 config['DEFAULT']['ForwardX11'] = 'yes' 13 with open('example.ini', 'w') as configfile: 14 config.write(configfile)
其实本质上就是一个字典,下面我们来读取一下这个配置文件的内容:
1 import configparser 2 config = configparser.ConfigParser() 3 config.read("example.ini") #先读配置文件 4 # print(config.sections()) 5 # print(config.default_section) 6 default = config.default_section 7 print(default) 8 print('ServerAliveInterval= %s\nCompressionLevel=%s ForwardX11=%s' 9 %(config[default]['ServerAliveInterval'],config[default]['CompressionLevel'],config[default]['ForwardX11']))
上面就是配置文件的读取,各位大神在写代码的时候可以使用配置文件配置一些参数。
九、logging模块
1 # -*- coding:utf-8 -*- 2 import logging 3 logging.basicConfig(filename='12.log', 4 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', 5 datefmt='%Y-%m-%d %H:%M:%S %p', 6 level=10) 7 #help(logging) 8 #%(asctime)s:表示datefmt的值 %(name)s:表示root %(levelname)s:表示bug的等级(debug,info,warning,error,critical,log) 9 #%(module)s:模块名称 %(message)s' 日志信息 10 logging.debug(u'打印debug信息') 11 logging.info('打印info信息') 12 logging.warning('打印warning信息') 13 logging.error('打印error信息') 14 logging.critical('打印critical信息') 15 logging.log(10,'log日志')
十、re模块
用于正则表达式
1 '.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 2 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) 3 '$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以 4 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a'] 5 '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb'] 6 '?' 匹配前一个字符1次或0次 7 '{m}' 匹配前一个字符m次 8 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] 9 '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC' 10 '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c 11 12 13 '\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的 14 '\Z' 匹配字符结尾,同$ 15 '\d' 匹配数字0-9 16 '\D' 匹配非数字 17 '\w' 匹配[A-Za-z0-9] 18 '\W' 匹配非[A-Za-z0-9] 19 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t' 20 [^a] 表示不包含a 21 '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
下面看一下正则表达式的几个栗子:
1 import re 2 re.match(".","hello123") #匹配一个字符h 3 re.match("\d","hello123") #匹配不到 以为match只从开头开始匹配字符串开头是h不是数字 4 re.search("\d","hello123")#可以匹配 search方法会从每个位置开始匹配 匹配1 5 re.search("[0-9]{1,3}","1212edddsds121wedw12wewd1ww2weew2") #执行结果<_sre.SRE_Match object; span=(0, 3), match='121'> 6 re.findall("[0-9]{1,3}","1212edddsds121wedw12wewd1ww2weew2") #执行结果['121', '2', '121', '12', '1', '2', '2'] 7 #search方法只匹配一个,findall会匹配所有 8 re.split(":","id:123:name:hello") #分割 9 re.sub("\d+","#","123fghjlfs12lll33$$") #替换 10 #下面来个实际的列子 1、找出所有150开头的手机号码 11 info = "18001452550ghsldllsa454115800513051,23443,15021487541fsafdafdsfa" 12 print(re.findall("150[0-9]{8}",info)) #执行结果['15021487541']
问题:如何判断判断一个字符串是小数?
如果使用正则表达式来做的话会非常简洁和方便。
1 def isFloat(express): 2 if re.search("^(-?\d+)\.(\d+)$",express): 3 return True 4 else: 5 return False
十一、hashlib模块和 hmac模块
主要用于加密
import hashlib m = hashlib.md5() m.update(b"Hello") m.update(b"It's me") print(m.digest()) m.update(b"It's been a long time since last time we ...") print(m.digest()) #2进制格式hash print(len(m.hexdigest())) #16进制格式hash ''' def digest(self, *args, **kwargs): # real signature unknown """ Return the digest value as a string of binary data. """ pass def hexdigest(self, *args, **kwargs): # real signature unknown """ Return the digest value as a string of hexadecimal digits. """ pass ''' import hashlib # ######## md5 ######## hash = hashlib.md5() hash.update('admin') print(hash.hexdigest()) # ######## sha1 ######## hash = hashlib.sha1() hash.update('admin') print(hash.hexdigest()) # ######## sha256 ######## hash = hashlib.sha256() hash.update('admin') print(hash.hexdigest()) # ######## sha384 ######## hash = hashlib.sha384() hash.update('admin') print(hash.hexdigest()) # ######## sha512 ######## hash = hashlib.sha512() hash.update('admin') print(hash.hexdigest())
python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;
一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了
1 import hmac 2 h = hmac.new('天王盖地虎'.encode("utf-8"), '宝塔镇河妖'.encode("utf-8")) 3 print(h.hexdigest())
我了个擦,终于写完模块这一节,累哥了!