python基础之模块
内置模块
------------------------------------------------------------------------
模块定义:模块就是别人写好的代码,放下一个py文件里,给你使用
但import加载的模块分为四个通用类型:
1)使用python编写好的代码(py文件)
2)已被编译为共享库或DLL的c或c++扩展
3)包好一组模块的包
4)使用c编写并连接到python解释器的内置模块
模块有几种那?
大致可分为三种: 内置模块 //// 自定义模块 //// 第三方模块
说了这么多,那我们为啥要用模块?
------写好了之后让你用,方便了用户的使用,提高了开发效率
------为了节省内存,所以把常用的(但是不是每一个程序都必须用到的)函数\方法
------根据分类将这些函数分到不同的文件中存储起来
定义:是以文件的形式存储在硬盘中,你用的时候才开始存到内存.
那么时间模块有啥作用那?
1)计算代码执行时,测试效率
2)日志:程序执行(用户的行为)的记录
3)定时器
4)记录用户的重要时间:出生日期\注册日期\入职日期
在python中,通常有这三中方式来表示时间:时间戳,元组,格式化的时间字符串
1.时间戳(timestamp):通常来说,时间戳表示float时间:1542072130.3895912 ----给计算机用的
2.格式化的时间字符串(Format String):'19990-3-2'
%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 当前时区的名称 %% %号本身
3.元组(struct_time):
索引(index) | 属性(Attribute) | 值(Values) |
0 | tm_year(年) | 比如2018 |
1 | tm_mon(月) | 1-12 |
2 | tm_mday(日) | 1-31 |
3 | tm_hour(时) | 0-23 |
4 | tm_min(分) | 0-59 |
5 | tm_sec(秒) | 0-60 |
6 | tm_wday(weekday) | 0-6(0表示周一) |
7 | tm_yday(一年中的第几天) | 1-366 |
8 | tm_isdst(是否是夏令时) | 默认为0 |
三种时间格式:
#导入时间模块 >>>import time #时间戳 >>>time.time() 1500875844.800804 #时间字符串 >>>time.strftime("%Y-%m-%d %X") '2017-07-24 13:54:37' >>>time.strftime("%Y-%m-%d %H-%M-%S") '2017-07-24 13-55-04' #时间元组:localtime将一个时间戳转换为当前时区的struct_time time.localtime() time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=13, tm_min=59, tm_sec=37, tm_wday=0, tm_yday=205, tm_isdst=0
几种格式的转换
(localtime\gmtime)--------------------->(strftime)------->
时间戳(Timestamp)----------------结构化时间(struct_time)-------------------格式化时间(Format string)
(mktime)<-------------------------------------(strptime)<---------
import time print(time.time()) #当时时间戳 print(time.strftime('%Y-%m-%d %H:%M:%S')) #当时格式化时间 print(time.localtime()) #当时结构化时间 s=time.time() #时间戳转格式化 s1=time.gmtime(s) print(s1) s2=time.strftime('%Y-%m-%d %H:%M:%S',s1) print(s2) #格式化转时间戳 s3=time.strptime(s2,'%Y-%m-%d %H:%M:%S') print(s3) s4=time.mktime(s3) print(s4)
import random #随机小数 print(random.random()) #随机取0-1内的小数 print(random.uniform(1,10)) #随机取范围内的小数 #随机整数 print(random.randrange(0,5,2)) #随机取范围内的整数,第三个元素是步长(就是隔几位取值) print(random.randint(1,10)) #随机取范围内的整数 #随机取值 l=[1,2,3,4] print(random.choice(l)) #随机取一个值 print(random.sample(l,2)) #随机取值,根据第二个元素的大小来取几个 random.shuffle(l) # 随即打乱顺序 print(l)
取6位数验证码
def func(n=6): s='' for i in range(n): num=random.randint(0,9) s+=str(num) print(s) func()
定义: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.start
注意:os.stat('path/filename')获取文件/目录信息的结构说明
stat 结构
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)是创建时间(详细信息参见平台的文档)。
os模块的属性
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n" os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
import os # os.makedirs('t2.txt/2.txt,22.txt') #能创多个 # os.mkdir('t3.txt') #创建一个,不能一下创多个 # os.removedirs('t2.txt/2.txt') #只要都是一个,就全删了,不是就出错 # os.rmdir('t2.txt/2.txt,22.txt') #只能删除一个
定义:sys模块是与python解释器交互的一个接口
sys.argv #命令行参数List,第一个元素是程序本身路径 sys.exit(n) #退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version #获取python解释器程序的版本信息 sys.path #返回模块的搜索路径,初始化时使用pythonpath环境变量的值 sys.platform #返回操作系统平台名称
序列化模块(json/pickle)
定义:将原本的字典,列表等内容转换成一个字符串的过程就是序列化
序列化的目的:
1)以某种储存形式是自定义对象持久化
2)将对象从一个地方传递到另一个地方
2)使程序更具维护性
反序列化------->
字符串(str)--------------------------------- 数据结构
序列化<-----------
json
json模块提供了四个功能:dumps,dump,loads,load
import json dict={'k1':'v1','k2':'v2','k3':'v3'} str_dic=json.dumps(dict) print(type(str_dic),str_dic) #序列化:将一个字典转换成一个字符串 #注意:json转换完的字符串类型的字典中的字符串是由""表示的 print(type(json.loads(str_dic)),json.loads(str_dic)) #反序列化:将一个字符串格式的字典转换成一个字典 f = open('json_file','w') dic = {'k1':'v1','k2':'v2','k3':'v3'} json.dump(dic,f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close() f = open('json_file') dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 f.close() print(type(dic2),dic2)
pickle 功能同上
import pickle dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = pickle.dumps(dic) #转换成二进制 print(str_dic) dic2 = pickle.loads(str_dic) #读取转换的二进制 print(dic2) import time struct_time = time.localtime(1000000000) print(struct_time) f = open('pickle_file','wb') pickle.dump(struct_time,f) #用二进制写入文件 f.close() f = open('pickle_file','rb') struct_time2 = pickle.load(f) #读取写入的二进制文件内容 print(struct_time2.tm_year)
区别:
json,用于字符串和python数据类型键转换 (json是所有语言都能识别的数据结构)
pickle,用于python特有的类型和python的数据类型进行转换
定义:就是匹配字符串内容的一种规则
官方定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符,及这些特定字符的组合.
字符组:
正则 待匹配字符 匹配结果 说明 [0123456789] 8 True 在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配 [0123456789] a False 由于字符组中没有"a"字符,所以不能匹配 [0-9] 7 True 也可以用-表示范围,[0-9]就和[0123456789]是一个意思 [a-z] s True 同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示 [A-Z] B True [A-Z]就表示所有的大写字母 [0-9a-fA-F] e True 可以匹配数字,大小写形式的a~f,用来验证十六进制字符
字符:
元字符 匹配内容 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线 \s 匹配任意的空白符 \d 匹配数字 \n 匹配一个换行符 \t 匹配一个制表符 \b 匹配一个单词的结尾 ^ 匹配字符串的开始 $ 匹配字符串的结尾 \W 匹配非字母或数字或下划线 \D 匹配非数字 \S 匹配非空白符 a|b 匹配字符a或字符b () 匹配括号内的表达式,也表示一个组 [...] 匹配字符组中的字符 [^...] 匹配除了字符组中字符的所有字符 量词:
量词 用法说明 * 重复零次或更多次 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次
正则 待匹配字符 匹配结果 说明 海. 海燕海娇海东 海燕海娇海东 匹配所有"海."的字符 ^海. 海燕海娇海东 海燕 只从开头匹配"海." 海.$ 海燕海娇海东 海东 只匹配结尾的"海.$" 李.? 李杰和李莲英和李二棍子 李杰李莲李二 ?表示重复零次或一次,即匹配"李"后面一个任意字符 李.* 李杰和李莲英和李二棍子 李杰和李莲英和李二棍子 *表示重复零次或多次,即匹配"李"后面0或多个任意字符 李.+ 李杰和李莲英和李二棍子 李杰和李莲英和李二棍子 +表示重复一次或多次,即只匹配"李"后面1个或多个任意字符 李.{1,2} 李杰和李莲英和李二棍子 李杰和李莲英李二棍 {1,2}匹配1到2次任意字符 李.*? 李杰和李莲英和李二棍子 李李李 惰性匹配 李[杰莲英二棍子]* 李杰和李莲英和李二棍子 李杰李莲英 表示匹配"李"字后面[李二棍子 杰莲英二棍子]的字符任意次 李[^和]* 李杰和李莲英和李二棍子 李杰李莲英李二棍子 表示匹配一个不是"和"的字 符任意次 [\d] 456bdha3 4 5 6 3 表示匹配任意一个数字,匹配到4个结果 [\d]+ 456bdha3 456 3 表示匹配任意个数字,匹配到2个结果
正则 待匹配字符 匹配结果 说明 \n \n False 因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本 身,用表达式\n无法匹配 \\n \n True 转义\之后变成\\,即可匹配 "\\\\n" '\\n' True 如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次 r'\\n' r'\n' True 在字符串之前加r,让整个字符串不转义
贪婪匹配
正则 待匹配字符 匹配结果 说明 <.*> <script>...<script> <script>...<script> 默认为贪婪匹配模式,会匹配尽量长的字符串 <.*?> r'\d' <script><script> 加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串
几个常用的非贪婪匹配pattern
*? 重复任意次,但尽可能少重复 +? 重复1次或更多次,但尽可能少重复 ?? 重复0次或1次,但尽可能少重复 {n,m}? 重复n到m次,但尽可能少重复 {n,}? 重复n次以上,但尽可能少重复
re模块下的常用方法
import re ret=re.findall('a','asdfoecvxcpefkeaa') #返回所有满足匹配条件的结果,放在列表里 print(ret) #['a', 'a', 'a'] ret1=re.search('a','bbafs') #如果字符串里面有要找的元素,就返回生成器,需要group()取值,如果没有就报错,只能一个一个取 print(ret1) #<_sre.SRE_Match object; span=(2, 3), match='a'> print(ret1.group()) #a ret2=re.match('a','asdsdawsf') #只能取第一位元素,如果是需要的就返回生成器,需要用group()取值,,不是返回None, print(ret2) #<_sre.SRE_Match object; span=(0, 1), match='a'> print(ret2.group()) #a ret3=re.split('a','dsfasfs') #分割,用啥分割,就在那分割 print(ret3) #['dsf', 'sfs'] ret4=re.sub('\d','H','sdasdf5sds5ds',1) #替换 把数字替换成'H' 参数1表示只替换一个 print(ret4) #sdasdfHsds5ds ret5=re.subn('\d','H','sdasdf5sds5ds') #替换,有多少替换多少,返回元组(并显示替换了多少) print(ret5) #('sdasdfHsdsHds', 2) obj=re.compile('\d{3}') #查找三个数字 ret6=obj.search('sdsfssfs125') print(ret6.group()) #125 num=re.finditer('\d','dsda2df556fw') print(num) #迭代器 print(next(num).group()) #返回第一个结果 print(next(num).group()) #返回第二个结果
注意:
1.findall的优先级查询
import re ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com') print(ret) # ['oldboy'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可 ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com') print(ret) # ['www.oldboy.com']
2.split的优先级查询
ret=re.split("\d+","eva3egon4yuan") print(ret) #结果 : ['eva', 'egon', 'yuan'] ret=re.split("(\d+)","eva3egon4yuan") print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan'] #在匹配部分加上()之后所切出的结果是不同的, #没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项, #这个在某些需要保留匹配部分的使用过程是非常重要的。
在线测试工具 http://tool.chinaz.com/regex/
定义:摘要算法又称哈希算法,散列算法.他通过一个函数,把任意长度的数据转换为一个长度固定德尔数据串(通常用十六进制的字符串表示)
两个常用的:hashlib.md5和hashlib.sha1
hashlib.md5 ##最通用\最快捷\相对简单
hashlib.sha1 ##已经开始被大家广泛应用
# md5_obj = hashlib.md5() # md5_obj.update('alex3714'.encode('utf-8')) # ret = md5_obj.hexdigest() # print(ret)
sha1同上
动态加盐-----最安全的储存密码的方式
# md5_obj = hashlib.md5('任意字符串'.encode('utf-8')) # md5_obj.update(pwd.encode('utf-8')) # ret = md5_obj.hexdigest() # print(ret)
如果要登录,也要用相同的模式
用处:该模块使用于配置文件的格式与windows ini文件类似,可以包含一个或多个节,每个节可以有多个参数(键=值)
一个好多软件的常见文档格式如下:
[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [bitbucket.org] User = hg [topsecret.server.com] Port = 50022 ForwardX11 = no
如何生成一个文档那
import configparser config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9', 'ForwardX11':'yes' } config['bitbucket.org'] = {'User':'hg'} config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} with open('example.ini', 'w') as configfile: config.write(configfile)
查文件
import configparser config = configparser.ConfigParser() #---------------------------查找文件内容,基于字典的形式 print(config.sections()) # [] config.read('example.ini') print(config.sections()) # ['bitbucket.org', 'topsecret.server.com'] print('bytebong.com' in config) # False print('bitbucket.org' in config) # True print(config['bitbucket.org']["user"]) # hg print(config['DEFAULT']['Compression']) #yes print(config['topsecret.server.com']['ForwardX11']) #no print(config['bitbucket.org']) #<Section: bitbucket.org> for key in config['bitbucket.org']: # 注意,有default会默认default的键 print(key) print(config.options('bitbucket.org')) # 同for循环,找到'bitbucket.org'下所有键 print(config.items('bitbucket.org')) #找到'bitbucket.org'下所有键值对 print(config.get('bitbucket.org','compression')) # yes get方法Section下的key对应的value
增删改操作
import configparser config = configparser.ConfigParser() config.read('example.ini') config.add_section('yuan') #增 config.remove_section('bitbucket.org') #删 config.remove_option('topsecret.server.com',"forwardx11") config.set('topsecret.server.com','k1','11111') #改 config.set('yuan','k2','22222') config.write(open('new2.ini', "w"))
函数式简单配置
import logging logging.debug('debug message') #最细节的 计算机计算的那些小过程 logging.info('info message') #普通的 记录每个用户的操作 logging.warning('warning message' ) #警告信息 你觉得可能会影响到你的程序的安全\正确 logging.error('error message') #错误信息 直接影响你程序的健康了 logging.critical('critical message' ) #批判的 把整个userinfo文件删除掉了
灵活配置日志级别,日志格式,输出位置:
import logging logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='/tmp/test.log', filemode='w') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
配置参数
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用户输出的消息
logger对象配置
import logging # logger对象的方式 : 灵活性 可扩展性 logger = logging.getLogger() # 创建一个logger对象 logger.setLevel(logging.DEBUG) # 创建一个文件操作符 来准备操作日志向文件中写这件事 fh = logging.FileHandler('mylog.log',encoding='utf-8') fh2 = logging.FileHandler('mylog2.log',encoding='utf-8') # 创建一个屏幕操作符 来准备操作日志向屏幕中写这件事 sh = logging.StreamHandler() # 创建一个输出格式 formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s') formatter2 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 组合 # 输出格式和文件操作符\屏幕操作符绑在一起 fh.setFormatter(formatter) sh.setFormatter(formatter2) sh.setLevel(logging.ERROR) # logger对象分别和文件操作符\屏幕操作符绑在一起 logger.addHandler(fh) logger.addHandler(fh2) logger.addHandler(sh) # 才开始能够使用logger来记录日志 logger.debug('debug message') logger.info('info message') logger.warning('warning message') logger.error('error message') logger.critical('critical message')
logging库提供了多个组件:logger,Handler,Fitter,Formatter
1)logger对象提供了应用程序可以直接使用的接口
2)Handler发送日志到适当的目的地
3)Fitter提供了过滤日志文信息的方法
4)Formatter指定日志显示格式
fh.setLevel(logging.Debug)单对文件流设置某个级别。