第四章节
1、什么是模块
在Python中,一个.py文件就可以称之为一个模块
2、模块的好处
最大的好处是大大提高了代码的可维护性
使用模块还可以避免函数名和变量名冲突
3、模块的分类
1.标准模块(标准库、内置模块)
有近300个,随时可以调用
2.第三方模块
近18w个左右
需要单独安装 pip install
3.自定义模块
自己写的
模块的导入和调用
import
from os import rename,path,replace
rename()
path()
replace()
模块的导入要写在首行
模块的调用方法:
mport module from module import xx from module.xx.xx import xx as rename from module.xx.xx import *
自定义模块
模块的查找路径:
全局能导入:
把文件放到第三方模块的路径下,就可以实现全局调用
第三方模块的安装和使用
https://pypi.org/
直接pip安装
pip命令会自动下载模块包病完成安装
软件一般会被自动安装你python安装目录的这个字目录里:
/your_python_install_path/3.6/lib/python3.6/site-packages
sudo pip install -i http://pypi.douban.com/simple/ alex_sayhi --trusted-host pypi.douban.com #alex_sayhi是模块名
OS模块
程序与系统的交互功能
得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd
>>> os.getcwd() 'C:\Users\hanjj20688' >>>
返回指定目录下的所有文件和目录名:os.listdir()
>>> os.listdir() ['.PyCharm2018.3', '3D Objects', 'AppData', 'Application Data', 'Contacts', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Evernote', 'Favorites', 'IntelGraphicsProfiles', 'Links', 'Local Settings', 'MicrosoftEdgeBackups', 'Music', 'My Documents', 'NetHood', 'NTUSER.DAT', 'ntuser.dat.LOG1', 'ntuser.dat.LOG2', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TM.blf', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000001.regtrans-ms', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000002.regtrans-ms', 'ntuser.ini', 'ntuser.pol', 'Pictures', 'PrintHood', 'Recent', 'Saved Games', 'Searches', 'SendTo', 'Templates', 'Videos', '「开始」菜单'] >>>
获取当前路径下的文件
>>> os.listdir(".") ['.PyCharm2018.3', '3D Objects', 'AppData', 'Application Data', 'Contacts', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Evernote', 'Favorites', 'IntelGraphicsProfiles', 'Links', 'Local Settings', 'MicrosoftEdgeBackups', 'Music', 'My Documents', 'NetHood', 'NTUSER.DAT', 'ntuser.dat.LOG1', 'ntuser.dat.LOG2', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TM.blf', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000001.regtrans-ms', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000002.regtrans-ms', 'ntuser.ini', 'ntuser.pol', 'Pictures', 'PrintHood', 'Recent', 'Saved Games', 'Searches', 'SendTo', 'Templates', 'test', 'test.txt', 'Videos', '「开始」菜单'] >>>
函数用来删除一个文件:os.remove()
>>> os.remove("试验用.txt") >>> os.remove("那些人.txt")
删除多个目录:os.removedirs(r“c:python”)
?
检验给出的路径是否是一个文件:os.path.isfile()
检验给出的路径是否是一个目录:os.path.isdir()
判断是否是绝对路径:os.path.isabs()
检验给出的路径是否真地存:os.path.exists()
返回一个路径的目录名和文件名:os.path.split() e.g os.path.split('/home/swaroop/byte/code/poem.txt') 结果:('/home/swaroop/byte/code', 'poem.txt')
分离扩展名:os.path.splitext() e.g os.path.splitext('/usr/local/test.py') 结果:('/usr/local/test', '.py')
获取路径名:os.path.dirname()
获得绝对路径: os.path.abspath()
打印当前脚本所在的路径,包含文件名【打印的是绝对路径】
import os
print(__file__)
输出
D:pyLearningvenvScriptspython.exe D:/py/Learning/第四模块/account.json.py D:/py/Learning/第四模块/account.json.py
获取文件名:os.path.basename()
运行shell命令: os.system()
读取操作系统环境变量HOME的值:os.getenv("HOME")
返回操作系统所有的环境变量: os.environ
设置系统环境变量,仅程序运行时有效:os.environ.setdefault('HOME','/home/alex')
给出当前平台使用的行终止符:os.linesep Windows使用'
',Linux and MAC使用'
'
指示你正在使用的平台:os.name 对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'
重命名:os.rename(old, new)
>>> os.listdir(".") ['.PyCharm2018.3', '3D Objects', 'AppData', 'Application Data', 'Contacts', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Evernote', 'Favorites', 'IntelGraphicsProfiles', 'Links', 'Local Settings', 'MicrosoftEdgeBackups', 'Music', 'My Documents', 'NetHood', 'NTUSER.DAT', 'ntuser.dat.LOG1', 'ntuser.dat.LOG2', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TM.blf', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000001.regtrans-ms', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000002.regtrans-ms', 'ntuser.ini', 'ntuser.pol', 'Pictures', 'PrintHood', 'Recent', 'Saved Games', 'Searches', 'SendTo', 'Templates', 'test', 'test.txt', 'Videos', '「开始」菜单'] >>> os.rename("test.txt","test22.txt") >>> os.listdir(".") ['.PyCharm2018.3', '3D Objects', 'AppData', 'Application Data', 'Contacts', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Evernote', 'Favorites', 'IntelGraphicsProfiles', 'Links', 'Local Settings', 'MicrosoftEdgeBackups', 'Music', 'My Documents', 'NetHood', 'NTUSER.DAT', 'ntuser.dat.LOG1', 'ntuser.dat.LOG2', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TM.blf', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000001.regtrans-ms', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000002.regtrans-ms', 'ntuser.ini', 'ntuser.pol', 'Pictures', 'PrintHood', 'Recent', 'Saved Games', 'Searches', 'SendTo', 'Templates', 'test', 'test22.txt', 'Videos', '「开始」菜单']
创建多级目录:os.makedirs(r“c:python est”)
创建单个目录:os.mkdir(“test”)
获取文件属性:os.stat(file)
>>> os.listdir(".") ['.PyCharm2018.3', '3D Objects', 'AppData', 'Application Data', 'Contacts', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Evernote', 'Favorites', 'IntelGraphicsProfiles', 'Links', 'Local Settings', 'MicrosoftEdgeBackups', 'Music', 'My Documents', 'NetHood', 'NTUSER.DAT', 'ntuser.dat.LOG1', 'ntuser.dat.LOG2', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TM.blf', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000001.regtrans-ms', 'NTUSER.DAT{8ebe95f7-3dcb-11e8-a9d9-7cfe90913f50}.TMContainer00000000000000000002.regtrans-ms', 'ntuser.ini', 'ntuser.pol', 'Pictures', 'PrintHood', 'Recent', 'Saved Games', 'Searches', 'SendTo', 'Templates', 'test', 'test22.txt', 'Videos', '「开始」菜单'] >>> os.stat("test22.txt") os.stat_result(st_mode=33206, st_ino=22799473113716506, st_dev=906384342, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1568032366, st_mtime=1568032366, st_ctime=1568032366) >>>
修改文件权限与时间戳:os.chmod(file)
获取文件大小:os.path.getsize(filename)
结合目录名与文件名:os.path.join(dir,filename)
改变工作目录到dirname: os.chdir(dirname)
获取当前终端的大小: os.get_terminal_size()
杀死进程: os.kill(10884,signal.SIGKILL)
sys模块
time模块
对时间处理,有如下三种操作
时间的显示
时间的转换
时间的运算
通常有这几种方式来表示时间
1. 时间戳
2. 格式化的时间字符串 如2019-09-22
3. 元祖(9个元素)即struct_time
time.time() 返回当前时间的时间戳
import time print(time.time()) #返回当前时间的时间戳
time.localtime() 将一个时间戳转换为当前时区struct_time(元祖)
import time print(time.localtime())
time.gmtime() 跟time.localtime()相似,将一个时间戳转换为UTC时区的struct_time(元祖)
print(time.localtime()) print(time.gmtime())
<<<
D:py_lisedaydayvenvScriptspython.exe D:/py_lise/dayday/第四章节/test1.py time.struct_time(tm_year=2019, tm_mon=9, tm_mday=22, tm_hour=23, tm_min=13, tm_sec=4, tm_wday=6, tm_yday=265, tm_isdst=0) time.struct_time(tm_year=2019, tm_mon=9, tm_mday=22, tm_hour=15, tm_min=13, tm_sec=4, tm_wday=6, tm_yday=265, tm_isdst=0)
time.mktime 将一个struct_time(元祖)转换为时间戳
print(time.mktime(time.localtime())) >>> 1569165404.0
time.sleep(secs) 线程推迟指定的时间运行
time.sleep(5) print("----------------")
time.asctime(t) 把一个表示时间的元祖或者struct_time表示为这种形式:Sun Sep 22 23:24:19 2019v,如果没有参数,将会将time.locatime()作为参数参入
print(time.asctime()) <<< Sun Sep 22 23:24:19 2019
time.strftime() 把一个代表时间的元祖或者struct_time转化为格式化的时间字符串
t1=time.strftime("%Y-%m-%d") print(t1)
time.strptime() 把一个格式化的时间字符串转化为struct_time,和time.strftime() 向逆
print(time.strptime("2020-3-10" ,"%Y-%m-%d"))
print(time.strptime("2020-3-10 19:30","%Y-%m-%d %H:%M"))
datetime模块
datetime模块定义了下面这些类:
datetime.date:表示日期的类,常用的属性有year,month,day
>>> datetime.date.today() datetime.date(2020, 3, 10) >>>
datetime.datetime:表示日期时间
- d=datetime.datetime.now() 返回当前的datetime日期类型
>>> datetime.datetime.now() datetime.datetime(2020, 3, 10, 20, 0, 7, 276440) >>>
datetime.timedelta:表示时间间隔,即两个时间点之间的长度
时间运算
>>> datetime.datetime.now() datetime.datetime(2020, 3, 10, 20, 8, 29, 194335) >>> datetime.datetime.now()+datetime.timedelta(4) datetime.datetime(2020, 3, 14, 20, 9, 15, 596157) >>>
>>> datetime.datetime.now()+datetime.timedelta(hours=3) datetime.datetime(2020, 3, 10, 23, 10, 33, 309874) >>>
random 随机数模块
验证码
命名规范:random_mod.py
1.random.randrange >>返回1-10之间的一个随机数,不包括10
import random random.randint(1,10)
2.random.randint(1,10) >>返回1-10之间的一个随机数,包括10
>>> random.randint(1,10) 9 >>>
3. random.randrange(0,100,2) 随机选择0-100的偶数
import random print(random.randrange(0,100,2))
4.random.rangdom() 返回一个随机浮点数
import random print(random.random())
5.random.choice()返回一个给定数据集合中的随机字符
import random print(random.choice('avfsdd$98'))
6.random.sample() 从多个字符中选取特定数量的字符
import random print(random.sample('avfsdd$98',3))
string 生成随机字符串
1. string.ascii_lowercase 返回有序的小写字符
import string print(string.ascii_lowercase)
2.string.digits
import string print(string.ascii_lowercase) print(string.digits)
生成随机字符串
import string import random a=string.ascii_lowercase+string.digits print(a) b=random.sample(a,5) print("".join(b))
洗牌
import string import random a=string.digits print(a) b=list(a) print(b) random.shuffle(b) print(b)
序列化pick&json模块
import pickle
d = {'k1':'v1','k2':'v2'}
f_dumps = pickle.dumps(d) #序列化
d_dumps = pickle.loads(f_dumps) #反序列化
print(d_dumps)
f = open("game.pkl","wb")
pickle.dump(d,f)
import pickle f = open("game.pkl","rb") d1=pickle.load(f) print(d1)
dump 写入文件
dumps 生成序列化的字符串
load 从文件加载
loads 把序列化的字符串反向解析
json VS pickle
import json d = {'k1':'v1','k2':'v2'} json_1 = json.dumps(d) print(json_1) print(type(json_1))
输入:
{"k1": "v1", "k2": "v2"} <class 'str'>
import json d = {'k1':'v1','k2':'v2'} # json_1 = json.dumps(d) # print(json_1) # print(type(json_1)) f = open("json.json","w") json_2 = json.dump(d,f) print(json_2)
import json f = open("json.json","r") json_3 = json.load(f) print(json_3)
区别
json:
支持所有语言
只支持常规的数据类型,str,int, dict, list ,tuple
pickle:
只支持python
支持python里所有的数据类型
hashlib 加密
散列
hash碰撞
两个不同的输入,转化成相同的输出
在当前进程下,hash出的值是唯一,如果退出则变掉了
加密算法在hash的基础上加工而成的
MD5
可以产生128位的散列值
特点“
1、压缩性
2、容易计算
3、抗修改性
4、强抗碰撞
MD5 不可逆
MD5的用途
1、防止篡改
2、防止看到明文
3、防止抵赖(数字签名)
SHA-1
安全hash算法
160位
升级SHA-256
文件copy模块shutil
正则表达式
字符串的匹配规则,
. 默认匹配除 之外的任意一个字符,
>>> re.search(".","abcddd") <re.Match object; span=(0, 1), match='a'> >>>
^ 匹配字符开头
>>> re.search("^a","abcddd") <re.Match object; span=(0, 1), match='a'> >>> re.search("^abc","abcddd") <re.Match object; span=(0, 3), match='abc'> >>>
$ 匹配字符结尾
>>> re.search("abc$","abcdddabc") <re.Match object; span=(6, 9), match='abc'> >>>
* 匹配*号前的字符0次或多次
>>> re.search("a*","aaaaaaaaaaaaaabcabcdddabc") <re.Match object; span=(0, 14), match='aaaaaaaaaaaaaa'> >>>
+ 匹配前一个字符1次或多次
>>> re.findall("aa+","aa9900888") ['aa'] >>> re.findall("aa+","aaaaaaa9900888") ['aaaaaaa'] >>> re.findall("aa+","aaaaaaa9900888aaa") ['aaaaaaa', 'aaa'] >>> re.findall("aa+","aaaaaaa990088aaa8aaa") ['aaaaaaa', 'aaa', 'aaa'] >>>
? 匹配前一个字符1次或0次
>>> re.search("a?","aaaaaaaaaaaaaabcabcdddabc") <re.Match object; span=(0, 1), match='a'> >>>
{m} 匹配前一个字符m次
>>> re.search('b{3}','alexbbbs').group() 'bbb' >>>
{n,m} 匹配一个字符n到m次
>>> re.findall('b{2,3}','bbalbbbbexbbbs') ['bb', 'bbb', 'bbb'] >>>
| 匹配左或右的字符
>>> re.search('b|a','alexbbbs').group() 'a' >>> re.search('b|a','balexbbbs').group() 'b' >>>
(……) 分组匹配,
>>> re.search("(abc){2}a(123|45)", "abcabca456c").group() 'abcabca45' >>>
A 只从字符开头匹配
>>> re.search('Aa','abalexbbbs') <re.Match object; span=(0, 1), match='a'> >>>
匹配字符结尾 同$
>>> re.search('a','balexbbbsa') <re.Match object; span=(9, 10), match='a'> >>>
d 匹配数字0-9 且只匹配一次
>>> re.search('d','balexbb89999') <re.Match object; span=(7, 8), match='8'> >>>
D 匹配非数字 且只匹配一次
>>> re.search('D','balexbb89999') <re.Match object; span=(0, 1), match='b'> >>>
w 匹配【A-Za-z0-9】 只匹配一次
>>> re.search('w','balexbb89999') <re.Match object; span=(0, 1), match='b'> >>> re.search('w','9balexbb89999') <re.Match object; span=(0, 1), match='9'> >>>
W 匹配非【A-Za-z0-9】 只匹配一次
>>> re.search('W','9balexbb89999****') <re.Match object; span=(13, 14), match='*'> >>>
s 匹配空白字符、 、
、
只匹配一下
>>> re.search("s+","ab c1 3").group() ' ' >>> re.search("s+","ab c1 3").group() ' ' >>>
(?P……) 分组匹配
re的匹配语法有一下几种
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.split 以匹配到的字符当作列表分隔符
re.sub 匹配字符并替换
re.fullmatch 全部匹配
re.fullmatch
(pattern,string,flags=0)
pattern 正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式
目录结构:
包&跨目录导入
一个文件夹管理多个模块文件,
一个包就是一个文件夹,该文件下必须存在init.py
在主目录下,建一个入口文件 manage.py【有了入口文件,就是意味着程序从包的根目录开始导入,也就是可以跨目录调用了】
入口文件里面调用view模块,
然后view文件里面去调用settings模块
如下:
views调用settings
LOGING日志模块
日志级别:
从低到高:debug,info,watning,error,critial
1.把日志写到文件里
import logging #debug,info,watning,error,critial logging.basicConfig(filename="log.log",level=logging.INFO) logging.debug("user[alex]attempted wrong more than 3 times") logging.info("server is down") logging.warning("log is log")
输出结果:
新增一个文件,文件内容为: INFO:root:server is down WARNING:root:log is log
解释:
level=logging.INFO,也就是说只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。
自定义日志格式
import logging logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') logging.warning('log is log.')
输出
03/14/2020 08:11:41 PM log is log.
所有支持的格式
%(name)s Logger的名字
%(levelname)s 文本形式的日志格式
%(pathname)s 调用日志输出函数的模块的完整路径名,
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间浮点数表示
%(relativeGreated)d 输出日志信息时的,自Logger创建以来的毫秒数
%(asctime)s 字符串时间的当前时间,默认格式是2003-07-05 08:26:45,888 逗号后面的是毫秒
%(thread)d 线程ID
%(threadName)s 线程名
%(process)d 进程ID
%(message)s 用户输出的消息
日志同时输出到屏幕和文件
logger 提供了应用程序可以直接使用的接口
handler 将logger创建的日志记录发送到合适的目的输出
filter 提供了 细度设备来决定输出哪条日志记录
formatter 决定日志记录的最终输出格式
Logger
每个程序输出信息之前都要活得一个Logger
LOG=logging.getLogger("")
还可以绑定handler filter
Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高 Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
可以设置日志级别:
Logger.debug()、
Logger.info()、
Logger.warning()、
Logger.error()、
Logger.critical()
Handler
Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象
每个Logger可以附件多个Handler
logging.StreamHandler 可以向文件对象输出信息
logging.FileHandler 同StreamHandler类似,不过它可以打开文件
logging.handlers.RotatingFileHandler 管理文件大小,如果超过某个大小值,也会重新生成一个,
logging.handlers.TimedRotatingFileHandler 同RotatingFileHandler类似,间隔一定时间就 自动创建新的日志文件
formatter组件
可以和handler组合
日志级别:
全局的日志级别默认为warning
全局设置为debug 屏幕设置为info,如果输出的日志界别为debug,那么屏幕就不会打印
import logging #1.生成Logger对象 logger = logging.getLogger("mysql") logger.setLevel(logging.DEBUG) #logger.setLevel() #logger.addFilter() #logger.removeFilter() #logger.addHandler() #logger.removeHandler() #2.生成handler对象 cn=logging.StreamHandler() fn= logging.FileHandler("mysql.log") cn.setLevel(logging.INFO) #handler.setLevel() #handler.addFilter() #handler.removeFilter() #2.1 把handler对象绑定Logger logger.addHandler(fn) logger.addHandler(cn) #3.生成formatter对象 fn_formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') cn_formater=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') #3.1把formatter对象绑定handler fn.setFormatter(fn_formatter) cn.setFormatter(cn_formater) logger.debug("test log 1") logger.info("test log 2") logger.warning("test log 3 ")