文章目录
1 自定义模块
1)__name__
属性的使用
-
模块以脚本方式运行时,
__name__
是固定的字符串:__main__
-
模块以导入方式运行时,
__name__
就是本模块的名字 -
加
if __name__ == "__main__": pass
- 可以在模块导入时不执行在判断语句中出现的代码(函数执行打印之类的测试语句)
2)系统导入模块的路径问题
-
内存中:如果之前导入成功过的模块,直接使用已经存在的模块
-
内置路径中:安装目录/Lib(site-package目录下都是自己下载安装的第三方包)
-
PYTHONPATH:import时寻找模块的路径
-
sys.path: 是一个可修改的路径列表
# 将自建模块的路径添加到sys.path中 import sys sys.path.append('路径') # 将自建模块的相对路径添加到sys.path中 import sys import os sys.path.append(os.path.dirname(__file__) + '相对路径') # __file__ 当前脚本路径 os.path.dirname() 目标路径父路径 + 父路径下的新建模块路径
-
如果上述路径都找不到,就报错
3)导入模块的多种方式:
- import xxx:导入一个模块的所有成员
- import aaa,bbb:一次性导入多个模块的成员。不推荐这种写法,分开写。
- from xxx import a:从某个模块中导入指定的成员。
- from xxx import a,b,c:从某个模块中导入多个成员。
- from xxx import *:从模块中导入所有成员。
4)from xxx import * 控制成员被导入
默认情况下,所有的成员都会被导入。
__all__
是一个列表,用于表示本模块可以被外界使用的成员。元素是成员名的字符串。
注意:
__all__
只是对from xxx import *这种导入方式生效。其余的方式都不生效。
5)相对导入
-
针对某个项目中的不同模块之间进行导入,称为相对导入。
-
只有一种格式:from 相对路径 import xxx
-
相对路径:包含了点号的一个相对路径。
- . 表示的是当前的路径。
- …表示的是父路径。
- …表示的是父路径的父路径。
# 相对导入同项目下的模块
# from ..z import zz # 容易向外界暴露zz模块
from ..z.zz import *
# 不使用相对导入的方式,导入本项目中的模块
# 通过当前文件的路径找到z的路径
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)) + '/z')
from zz import *
2 random模块
此模块提供了和随机数获取相关的方法
- random.random():获取[0.0,1.0)范围内的浮点数
- random.randint(a, b):获取[a, b]范围内的一个整数
- random.uniform(a, b):获取[a, b)范围内的浮点数
- random.shuffle(x):把参数指定的数据中的元素打乱。参数必须是一个可变的数据类型。
- random.sample(x, k):从x中随机抽取k个数据返回一个列表
3 time模块
封装了获取时间戳和字符串形式的时间的一些方法。
1)获取时间戳
- 时间戳:从时间元年(1970 1 1 00:00:00)到现在经过的秒数
- 获取:time.time() 返回当前时间
2)获取格式化时间对象
- time.gmtime() # 打印GMT:格林威治时间–欧洲时间
- time.localtime() # 打印当地时间
- 参数
- 默认参数是当前系统时间的时间戳
- 自己设置参数,time.gmtime(1) # 时间元年过一秒后对应的时间对象
print(time.gmtime())
print(time.localtime())
'''
返回值:
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=3, tm_hour=11, tm_min=14, tm_sec=33, tm_wday=4, tm_yday=94, tm_isdst=0)
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=3, tm_hour=19, tm_min=14, tm_sec=33, tm_wday=4, tm_yday=94, tm_isdst=0)
注:欧洲人每周开始是星期0
'''
print(time.gmtime(1)) # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=1, tm_wday=3, tm_yday=1, tm_isdst=0)
-
时间对象 --> 时间戳
-
time.mktime(时间对象)
-
t1 = time.localtime() # 时间对象 t2 = time.mktime(t1) # 获取对应的时间戳 print(t2)
-
3)格式化时间对象和字符串之间的转换
-
时间对象 --> 字符串
-
time.strftime(‘格式’)
-
s = time.strftime('year:%Y %m %d %H:%M:%S') print(s) # year:2020 04 03 20:09:50
-
-
字符串 --> 时间对象
-
time.strptime(‘字符串’, ‘格式’)
-
times = time.strptime('2010 10 10', '%Y %m %d') print(times) # time.struct_time(tm_year=2010, tm_mon=10, tm_mday=10, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=283, tm_isdst=-1)
-
4)time模块的三大对象
- 格式化时间对象:time.struct_time
- 时间戳
- 时间字符串
- 三大对象之间的关系:
5)暂停当前进程,睡眠
-
time.sleep(秒数)
-
for i in range(5): print(time.strftime('%Y %m %d %H:%M:%S')) time.sleep(1) # 休眠一秒钟 ''' 2020 04 03 20:24:23 2020 04 03 20:24:24 2020 04 03 20:24:25 2020 04 03 20:24:26 2020 04 03 20:24:27 '''
4 datetime 日期时间模块
封装了一些和日期时间相关的类
1)date类
-
datetime.date(年, 月, 日)
-
获取date对象的各个属性。.year .month .day
import datetime d = datetime.date(2010,10,10) print(d) print(d.year) print(d.month) print(d.day) ''' 2010-10-10 2010 10 10 '''
2)time类
-
datetime.time(时, 分, 秒)
-
time类的属性。.hour .minute .second
t = datetime.time(10,48,59) print(t) print(t.hour) print(t.minute) print(t.second) ''' 10:48:59 10 48 59 '''
3)datetime类
-
datetime.datetime(年, 月, 日, 时, 分, 秒)
-
datetime类的属性。.year .month .day .hour .minute .second
dt = datetime.datetime(2010,11,11,11,11,11) print(dt) ''' 2010-11-11 11:11:11 '''
-
datetime中的类,主要是用于数学计算的.
4)timedelta类
-
timedelta:时间的变化量
-
datetime.timedelta(days=1)
td = datetime.timedelta(days=1) print(td) # 1 day, 0:00:00
-
参与数学运算,只能和以下三类进行数学运算: date,datetime,timedelta
td = datetime.timedelta(days=1)
d = datetime.date(2010,10,10)
res = d - td
print(res) # 2010-10-09
-
时间变化量的计算会产生进位
t = datetime.datetime(2010,10,10,10,10,00) td = datetime.timedelta(seconds=3) res = t - td print(res) # 2010-10-10 10:09:57
-
和时间段进行运算的结果类型:和另一个操作数保持一致
d = datetime.date(2010,10,10) d = datetime.datetime(2010,10,10,10,10,10) d = datetime.timedelta(seconds=20) td = datetime.timedelta(days=1) res = d + td print(type(res)) # 2010-10-10 10:09:57 # <class 'datetime.timedelta'>
-
练习
# 练习:计算某一年的二月份有多少天. # 普通算法:根据年份计算是否是闰年.是:29天,否:28 # 用datetime模块. # 首先创建出指定年份的3月1号.然后让它往前走一天. year = int(input("输入年份:")) # 2020 # 创建指定年份的date对象 d = datetime.date(year,3,1) # 创建一天 的时间段 td = datetime.timedelta(days=1) res = d - td print(res.day) # 29 2月29天 2020是闰年
5 os模块
和操作系统相关的一些操作被封装到这个模块中
1)和文件操作相关
-
重命名
-
os.rename(原文件名, 改的文件名)
import os os.rename('a.txt','b.txt')
-
-
删除
-
删除文件 os.remove(‘文件名’)
os.remove('a.txt')
-
删除空目录 os.removedirs(目录名)
os.removedirs('aa')
-
删除带内容目录:使用shutil模块删除
import shutil shutil.rmtree('aa')
-
2)和路径相关操作
-
被封装到另一个子模块中:os.path
-
获取父目录
res = os.path.dirname(r'd:/aaa/bbb/ccc/a.txt') # 不判断路径是否存在,去掉文件名返回此文件的目录,若参数为相对路径,则输出空字符串 print(res)
-
获取文件名
res = os.path.basename(r'd:/aaa/bbb/ccc/a.txt') print(res)
-
把路径中的路径名和文件名切分开,结果是元组.
res = os.path.split(r'd:/aaa/bbb/ccc/a.txt') print(res)
-
拼接路径
path = os.path.join('d:\\','aaa','bbb','ccc','a.txt') print(path)
-
转换绝对路径
-
如果是/开头的路径,默认是在当前盘符下
res = os.path.abspath(r'/a/b/c')
-
如果不是以/开头,默认当前路径
res = os.path.abspath(r'a/b/c')
-
-
判断
-
绝对路径
print(os.path.isabs('a.txt'))
-
目录
print(os.path.isdir('d:/aaaa.txt')) # 文件不存在.False
-
文件是否存在
print(os.path.exists('d:/a.txt'))
-
是否文件
print(os.path.isfile('d:/asssss.txt')) # 文件不存在.False
-
6 sys 模块
-
和python解释器相关的操作
-
获取命令行方式运行的脚本后面的参数
import sys print("脚本名:",sys.argv[0]) # 脚本名 print("第一个参数:",sys.argv[1]) # 第一个参数 print("第二个参数:",sys.argv[2]) # 第二个参数 # print(type(sys.argv[1])) # str # 应用 # arg1 = int(sys.argv[1]) # arg2 = int(sys.argv[2]) # print(arg1 + arg2)
-
解释器寻找模块的路径
sys.path('')
-
返回已经加载的模块
print(sys.modules)
7 json模块
1)序列化
-
把内存中的数据,转换成字节或字符串的形式,以便于进行存储或者网络传输.
-
内存中的数据(结构化数据)
-
磁盘上的数据(线性数据)
-
序列化和反序列化的区别:
- 序列化:内存中数据 -> 字节串/字符串
- 反序列化:字节串/字符串 -> 内存中的数据 : 反序列化
2)json
- json是不完整的序列化:json将数据转换为字符串,用于存储或网络传输
- json.dumps(数据) # 将数据序列化为json字符串
import json
s = json.dumps([1,2,3]) # 把指定的对象转换成json格式的字符串
print(type(s))
print(s) # '[1,2,3]' [1,2,3]
s = json.dumps((1,2,3)) # 元组序列化后,变成列表
print(s)
res = json.dumps(10)
print(res) # '10'
res = json.dumps({'name':'Andy','age':10})
print(res) # '{"name": "Andy", "age": 10}'
res = json.dumps(set('abc')) # Object of type 'set' is not JSON serializable
-
json.dump(json, 文件) # 将序列化的json结果写入到文件中
with open('a.txt',mode='at',encoding='utf-8') as f: json.dump([1,2,3],f)
-
json.loads() # 将json字符串反序列化为数据
# 反序列化 res = json.dumps([1,2,3]) lst = json.loads(res) # 反序列化 print(type(lst)) print(lst) # 元组会变成列表 # res = json.dumps((1,2,3)) # lst = json.loads(res) # 反序列化 # print(type(lst)) # print(lst)
-
json.load() # 将json字符串从文件中反序列化
with open('a.txt',encoding='utf-8')as f: res = json.load(f) print(type(res)) print(res)
-
json文件通常是一次性写、一次性读。使用另一种方式,可以实现多次写、多次读。
# 把需要序列化的对象.通过多次序列化的方式, 用文件的write方法,把多次序列化后的json字符串 # 写到文件中. with open('json.txt',mode='at',encoding='utf-8') as f: f.write(json.dumps([1,2,3]) + '\n') f.write(json.dumps([4,5,5]) + '\n') # 把分次序列化的json字符串,反序列化回来 with open('json.txt',mode='rt',encoding='utf-8') as f: # res = json.loads(f.readline().strip()) # print(res) # res2 = json.loads(f.readline().strip()) # print(res2) # 使用循环改进: for x in f: print(json.loads(x.strip()))
8 pickle模块
1)序列化
- 序列化过程:将Python中所有的数据类型.转换成字节串
- 反序列化过程:将字节串转换成python中数据类型
2)序列化和反序列化方法
-
pickle.dumps() pickle.loads() # 所有python的数据类型都可以进行序列化和反序列化
bys = pickle.dumps(set('abc')) res = pickle.loads(bys) print(type(res))
-
pickle.dump() # 把pickle序列化内容写入文件中
with open('c.txt',mode='wb') as f:
pickle.dump([1,2,3],f)
-
pickle.load() # 从文件中反序列化pickle数据
with open('c.txt',mode='rb') as f: res = pickle.load(f) print(type(res)) print(res)
-
多次pickle序列化数据到同一个文件中
with open('c.txt',mode='ab') as f: pickle.dump([1,2,3],f) pickle.dump([1,2,3],f) pickle.dump([1,2,3],f)
-
多次pickle从文件中反序列化数据
with open('c.txt',mode='rb') as f: for x in range(4): res = pickle.load(f) print(res)
-
pickle常用场景:和json一样,一次性写入,一次性读取.
3)json和pickle的比较
- json
- 不是所有的数据类型都可以序列化.结果是字符串.
- 不能多次对同一个文件序列化.
- json数据可以跨语言
- pickle
- 所有python类型都能序列化,结果是字节串.
- 可以多次对同一个文件序列化
- 不能跨语言.
9 hashlib 模块
1)封装一些用于加密的类
2)加密目的
用于判断和验证,而并非解密
3)特点
-
把一个大的数据,切分成不同块,分别对不同的块进行加密,再汇总的结果,和直接对整体数据加密的结果是一致的.
m = hashlib.md5() m.update(b'abc') m.update(b'def') print(m.hexdigest()) n = hashlib.md5() n.update(b'abcdef') print(m.hexdigest()) # 与上面加密结果相同
-
单向加密,不可逆.
-
原始数据的一点小的变化,将导致结果的非常大的差异,'雪崩’效应.
4)数据加密
-
数据加密三大步骤
- 获取一个加密对象
- 使用加密对象的update,进行加密,update方法可以调用多次
- 通常通过hexdigest获取加密结果(字符串),或digest()方法(二进制).
import hashlib # 获取加密对象 m = hashlib.md5() # 使用加密对象的update,进行加密 m.update('abc加密'.encode('utf-8')) # .encode()进行转码 # 通过hexdigest获取加密结果 res = m.digest() res = m.hexdigest() print(res)
-
加密用途
验证:用另一个数据加密的结果和第一次加密的结果对比.
如果结果相同,说明原文相同.如果不相同,说明原文不同.
-
不同加密算法区别
不同加密算法实际上就是加密结果的长度不同.
s = hashlib.sha224() # 56位16进制,相当于224位二进制 s.update(b'abc') print(len(s.hexdigest())) print(len(hashlib.md5().hexdigest())) # 32位16进制,相当于128位二进制 print(len(hashlib.sha256().hexdigest())) # 64位16进制,相当于256位二进制
-
在创建加密对象时,可以指定参数,称为salt.不使用update()
# 指定参数 m = hashlib.md5(b'abc') print(m.hexdigest()) # 通过update()设置参数 m = hashlib.md5() m.update(b'abc') print(m.hexdigest())
5)实例
# 注册,登录程序:
def get_md5(username,passwd):
m = hashlib.md5(username[::-1].encode('utf-8'))
m.update(username.encode('utf-8'))
m.update(passwd.encode('utf-8'))
return m.hexdigest()
def register(username,passwd):
# 加密
res = get_md5(username,passwd)
# 写入文件
with open('login',mode='at',encoding='utf-8') as f:
f.write(res)
f.write('\n')
# username:xxxxxx
def login(username,passwd):
# 获取当前登录信息的加密结果
res = get_md5(username, passwd)
# 读文件,和其中的数据进行对比
with open('login',mode='rt',encoding='utf-8') as f:
for line in f:
if res == line.strip():
return True
else:
return False
while True:
op = int(input("1.注册 2.登录 3.退出"))
if op == 3 :
break
elif op == 1:
username = input("输入用户名:")
passwd = input("输入密码:")
register(username,passwd)
elif op == 2:
username = input("输入用户名:")
passwd = input("输入密码:")
res = login(username,passwd)
if res:
print('登录成功')
else:
print('登录失败')
10 collections模块
定义了一些常用容器类
1)namedtuple() # 命名元组
-
作用:创建一个tuple的子类,并添加属性
-
用法:
-
创建
-
通过属性访问元素
-
通过索引访问元素
from collections import namedtuple, defaultdict, Counter # 创建 Rectangle = namedtuple('Rectangle_class',['length','width']) # r = Rectangle(10,5) # 通过属性访问元组的元素 print(r.length) print(r.width) # 通过索引的方式访问元素 print(r[0]) print(r[1])
-
2)defaultdict() # 默认值字典
以键值对方式创建字典,当访问的key不存在时,默认创建不存在的key=默认参数返回值
-
默认参数:int 返回值:0
d = defaultdict(int,name='Andy',age=10) print(d['name']) print(d['age']) print(d['addr']) # {'addr':0} 也会被添加 print(d)
-
默认参数:自定义函数(不能有参数) 返回值:函数返回值
def f(): return 'hello' d = defaultdict(f,name='Andy',age=10) print(d['addr']) print(d)
3)Counter() # 计数器
c = Counter('abcdefabccccdd')
print(c) # Counter({'c': 5, 'd': 3, 'a': 2, 'b': 2, 'e': 1, 'f': 1})
print(c.most_common(3)) # [('c', 5), ('d', 3), ('a', 2)]