获取时间戳:
import time # 时间戳:从时间元年(1970-1-1 00:00:00)到现在经过的秒数 print(time.time()) # 输出 1618916107.9363585
获取格式化时间对象:就是九个字段组成的。年、月、日、时、分、秒、夏令时
默认参数是当前系统的时间戳:
import time print(time.gmtime(1)) # 时间元年过一秒后对应的时间对象 print(time.gmtime()) # GMT:格林尼治天文台时间,在欧洲,符合欧洲的时间。 print(time.localtime()) # 当地时间,也就是我现在的时间 # 输出 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.struct_time(tm_year=2021, tm_mon=4, tm_mday=20, tm_hour=11, tm_min=12, tm_sec=24, tm_wday=1, tm_yday=110, tm_isdst=0) time.struct_time(tm_year=2021, tm_mon=4, tm_mday=20, tm_hour=19, tm_min=12, tm_sec=24, tm_wday=1, tm_yday=110, tm_isdst=0)
时间对象------>时间戳
time_obj = time.localtime() # 时间对象 # 把时间对象time_obj转换成时间戳 time_stamp = time.mktime(time_obj) print(time_stamp) # 输出 1618991181.0
格式化时间对象------>可读的时间字符串
import time print(time.strftime('%Y %m %d %H:%M:%S')) # 年月日 时分秒 # 输出 2021 04 20 19:18:11
把时间字符串------>时间对象
import time print(time.strptime('2021 4 20 19 25 2', '%Y %m %d %H %M %S')) # 输出 time.struct_time(tm_year=2021, tm_mon=4, tm_mday=20, tm_hour=19, tm_min=25, tm_sec=2, tm_wday=1, tm_yday=110, tm_isdst=-1)
暂停当前程序,睡眠xxx秒
import time time.sleep(2)
二、datetime:日期时间模块
封装了一些和日期,时间相关的类。
datetime
主要是用于数学计算的
data:类
包含年、月、日
import datetime d = datetime.date(2020, 5, 12) # 获取date对象的各个属性 print(d.year) print(d.month) print(d.day)
time:类
包含时、分、秒
import datetime t = datetime.time(10, 20, 55) print(t) # 获取time对象的各个属性 print(t.hour) print(t.minute) print(t.second)
timedelta:类---主要是用于数学计算的
时间的变化量
只能和date、datetime进行运算
import datetime td = datetime.timedelta(days=1) d = datetime.date(2020, 11, 11) res = d - td # 把2020-11-11给减去一天 print(res) # 输出 2020-11-10
时间变化量的计算是否会产生进位?
time类不可以和timedelta进行运算
import datetime td = datetime.datetime(2020, 11, 11, 11, 11, 59) t = datetime.timedelta(seconds=3) res = t + td # 给2020-11-11 11:11:59 加 3 秒 print(res) # 输出 2020-11-11 11:12:02 # 时间变化量的计算是会产生进位的
练习:计算某一年的二月份有多少天。 普通算法:根据年份计算是否是闰年。是:29天,否:28天 用datetime模块 首选创建出指定年月份的3月1号,然后让它往前走一天。
import datetime year = int(input('输入年份:')) # 创建指定年份的date对象 d = datetime.date(year, 3, 1) # 创建一天的时间段 td = datetime.timedelta(days=1) res = d - td print(res.day)
和时间段进行运算的结果类型是和前一个操作数相关:
import datetime td = datetime.timedelta(days=1) d1 = datetime.date(2020, 11, 11) # 和 date 一致 d2 = datetime.datetime(2020, 11, 11, 11, 11, 11)# 和datetime一致 res1 = d1 - td res2 = d2 - td print(type(res1), res1) print(type(res2), res2) # 输出 <class 'datetime.date'> 2020-11-10 <class 'datetime.datetime'> 2020-11-10 11:11:11
三、os模块
和操作系统相关的操作被封装到这个模块中。
和文件操作相关,
删除文件: os.remove ( )
import os os.remove(r'目录文件')
删除目录:os.removedirs ( ) 必须是空目录
import os os.removedirs(r'目录') # 目录下不能有文件
使用 shutil 模块可以删除带内容的目录
shutil.rmtree ( )
import shutil shutil.rmtree(r'目录或目录路径')
重命名: os.renames(a, b ) 把 a文件名 改成 b文件名目录名也可以修改
import os os.renames('a.txt', 'b.txt')
和路径相关的操作,被封装到另一个子模块中:os.path
os.path.dirname():不判断路径是否存在,只拿走路径
import os path = os.path.dirname(r'd:aaabbccca.txt') print(path) # 输出 d:aaabbccc
os.path.basename():不判断路径是否存在,只拿走文件名
import os path = os.path.basename(r'd:aaabbccca.txt') print(path) # 输出 a.txt
os.path.split():不判断路径是否存在,把路径中的路径名和文件名切分开返回两个元素的元组
import os path = os.path.split(r'd:aaabbccca.txt') print(path) # 输出 ('d:\aaa\bbb\ccc', 'a.txt')
os.path.join( 'd:/', 'aa', 'bb', 'cc.txt' ):拼接路径
import os path = os.path.join('aaa', 'bbb', 'ccc', 'a.txt') print(path) # 输出 aaabbccca.txt
os.path.abspath():返回绝对路径
import os path = os.path.abspath(r'a.txt') print(path) # 输出 C:UsersAdministratorDesktoppython练习a.txt
os.path.isabs():判断是否绝对路径,以盘符做为开头是绝对路径,
import os path1 = os.path.isabs(r'a.txt') path2 = os.path.isabs(r'D:a.txt') print(path1) print(path2) # 输出 False True
os.path.isdir():判断是否是目录,目录或文件不存在是 False
import os path1 = os.path.isdir(r'bb') #目录不存在也为False path2 = os.path.isdir(r'a.txt')#文件不存在或不是目录都为False print(path1) print(path2) # 输出 True False
os.path.exists():判断文件或目录是否存在,不存在是 False
import os path1 = os.path.exists(r'bb') path2 = os.path.exists(r'a.txt') print(path1) print(path2) # 输出 True True
os.path.isfile():只能判断文件是否存在,不存在False,
import os path1 = os.path.isfile(r'bb') # 目录返回False path2 = os.path.isfile(r'a.txt') print(path1) print(path2) # 输出 False True
os.path.islink():判断是否是链接
四、sys模块
和python解释器相关的操作
sys.argv[ ] 获取命令行方式运行的脚步后面的参数
就是为了让程序以脚步方式运行时在cmd命令行传入的参数
import sys print('脚本名:', sys.argv[0]) # 脚本名 a = sys.argv[1] # 第一个参数 b = sys.argv[2] # 第二个参数 c = int(a) + int(b) print(f'{a}+{b}=', c) # 在终端运行脚步时:传入参数 5 和 3 C:UsersYSDesktopPython全栈day16>python 练习.py 5 3 脚本名: 练习.py 5+3= 8
sys.path:解释器寻找模块的路径,可以增加路径让解释器去寻找我们指定路径下的模块
import sys path = sys.path print(path) # 输出 ['C:\Users\Administrator\Desktop\python\练习', 'C:\Users\Administrator\Desktop\python',........]
sys.modules:返回系统已经加载的模块,以字典形式返回。
import sys path = sys.modules print(path) # 输出 {'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, .......}
五、json模块
JavaScript object Notation:java脚本兑现标记语言。
是一种简单的数据交换格式。不完全的序列化
序列化:将内存中的数据,转换成字节用以保存在文件或通过网络传输,称为序列化过程。
json:将数据转换成字符串(不能转换set数据类型),用于存储或网络传输。(不太彻底转换到字节串的前一步字符串)
反序列化:从文件中,网络中获取的数据,转换成内存中原来的的数据类型,称为反序列化过程
json模块使用:
json.dumps:序列化,从内存----->内存
import json obj = json.dumps([1, 2, 3, 4]) print(type(obj), obj) # 输出 <class 'str'> [1, 2, 3, 4]
json.domp:序列化,将json结果写入文件中,内存------->文件
json.dump([1,2,3],文件句柄)
import json with open('obj.txt', encoding='utf-8', mode='wt') as f: json.dump([1, 2, 3, 4], f)
json.loads:反序列化,从内存------->内存,元组会变成列表。
import json # 先序列化列表 [1, 2, 3, 4]为字符串 obj1 = json.dumps([1, 2, 3, 4]) print(type(obj1), obj1) # <class 'str'> [1, 2, 3, 4] obj2 = json.loads(obj1) # 在反序列化为列表 print(type(obj2), obj2) # <class 'list'> [1, 2, 3, 4]
json.load:反序列化,从文件----->内存反序列化
json.load(文件句柄)
import json with open('obj.txt', encoding='utf-8', mode='rt') as f: # 将文件中的被序列化后的字符串反序列化回原来的字典类型 obj = json.load(f) print(type(obj),obj) # 输出 <class 'list'> [1, 2, 3, 4]
json文件通常是一次性写,一次性读,
使用另一种方式可以实现多次写,多次读。
把需要序列化的对象,通过多次序列化的方式,用文件的write方法,把多次序列化后的json字符串写到文件中
import json with open('obj.txt', encoding='utf-8', mode='w') as f: f.write(json.dumps([1, 2, 3, 4]) + ' ') f.write(json.dumps([5, 6, 7, 8]) + ' ')
把分次序列化的json字符串反序列化回来
import json with open('obj.txt', encoding='utf-8', mode='rt') as f1: obj1 = json.loads(f1.readline().strip()) obj2 = json.loads(f1.readline().strip()) print(type(obj1), obj1) print(type(obj2), obj2) # 输出 <class 'list'> [1, 2, 3, 4] <class 'list'> [5, 6, 7, 8]
六、pickle:
将python中所有的数据类型,直接转换成字节,这叫序列化过程,最彻底的序列化方式
将字节转换成python中数据类型,反序列化过程。
pickle:的用法
pickle.dumps:从内存-------> 内存的序列化
import pickle obj = pickle.dumps([1, 2, 3, 4]) print(obj) # 输出的是字节,bytes数据类型 b'x80x04x95 x00x00x00x00x00x00x00]x94(Kx01Kx02Kx03Kx04e.'
pickle.dump:从内存-------->文件的序列化
用 w 操作方式模式打开文件,用 b 为操作单位。
import pickle # 二进制模式(b)不能使用编码参数 encoding with open('obj.txt', mode='wb') as f: pickle.dump([1, 2, 3, 4], f)
pickle.loabs:从内存------>内存的反序列化
import pickle obj1 = pickle.dumps([1, 2, 3, 4]) # 先序列化成字节 print(type(obj1)) print(obj1) obj2 = pickle.loads(obj1) # 在反序列化回我原有的数据类型 print(type(obj2)) print(obj2) # 输出 <class 'bytes'> b'x80x04x95 x00x00x00x00x00x00x00]x94(Kx01Kx02Kx03Kx04e.' <class 'list'> [1, 2, 3, 4]
pickle.load:从文件------>内存中反序列化
with open('obj.txt', mode='rb') as f: obj = pickle.load(f) print(type(obj), obj) # 输出 <class 'list'> [1, 2, 3, 4]
pickle可以无限次数的操作同一个文件
import pickle with open('obj.txt', mode='wb') as f1: pickle.dump([1, 2, 3, 4], f1) pickle.dump([5, 6, 7, 8], f1) pickle.dump([9, 10, 11, 12], f1) pickle.dump([13, 14, 15, 16], f1) with open('obj.txt', mode='rb') as f2: for i in range(4): obj = pickle.load(f2) print(type(obj), obj) # 输出 <class 'list'> [1, 2, 3, 4] <class 'list'> [5, 6, 7, 8] <class 'list'> [9, 10, 11, 12] <class 'list'> [13, 14, 15, 16]
pickle常用的场景,一次读入,一次写入
七、json,pickle的比较
json:
1、不是所有的数据类型都可以序列化,结果是字符串。
2、不能多次对同一个文件序列化。
3、json数据可以跨语言
pickle:
1、所有的python类型都能序列化,结果是字节。
2、可以多次对同一个文件序列化
3、不能跨语言。
八、hashlib
封装一些用于加密的类
md5()
sha系列:随之sha系列数字越高,加密越复杂,越不容易被破解,但是耗时越长
加密的目的:用于判断和验证,而并非解密。
给一个数据加密,
验证:用另一个数据加密的结果和第一次加密的结果对比。
如果结果相同,说明原文相同,如果不相同,说明原文不同
不同加密算法:实际上就是加密结果长度不同;
s = hashlib.sha224() s.update('1中国'.encode('utf-8')) ss = s.hexdigest() print(ss) # 输出 3e2005cdfbc101b06367b0a1d3c2a9d25fcbf391a0f67a4d0cc0dfe0
特点:
把一个大的数据,切分成不同的小块,分别对不同的块进行加密,在汇总的结果,和直接对数据加密的结果是一致的。
import hashlib hash_obj1 = hashlib.md5() hash_obj1.update('123abc小杨'.encode('utf-8')) hash_obj1.update('opqlst'.encode('utf-8')) obj1 = hash_obj1.hexdigest() print(obj1) hash_obj2 = hashlib.md5() hash_obj2.update('123abc小杨opqlst'.encode('utf-8')) obj2 = hash_obj2.hexdigest() print(obj2) # 输出 f6de00d04ded3774ae46e2fff7bbbd46 f6de00d04ded3774ae46e2fff7bbbd46
单向加密,不可逆。(山东大学,王教授,研究出了md5的破解,就是撞库)
原始数据的一点小的变化,将导致结果的非常大的差异(雪崩效应)
使用方式:
1、获取一个加密对象
2、使用加密对象的update,进行加密,可以调用多次进行累计加密
3、通过hexdiges获取加密结果
import hashlib # 1、获取一个加密对象 hash_obj = hashlib.md5() # 2、使用加密对象的update,进行加密,可以调用多次进行累计加密 hash_obj.update('123abc小杨'.encode('utf-8')) # 第二次累积加密相当于对>>‘123abc小杨opqlst’进行加密 hash_obj.update('opqlst'.encode('utf-8')) # 3、通过hexdiges获取加密结果 obj = hash_obj.hexdigest() print(obj) # 输出 f6de00d04ded3774ae46e2fff7bbbd46
在创建加密对象时,可以指定参数,称为加盐:
import hashlib hash_obj = hashlib.md5('加的盐'.encode('utf-8')) hash_obj.update('123abc小杨opqlst'.encode('utf-8')) obj = hash_obj.hexdigest() print(obj) # 输出 5d81bdb5422fc66644f321ed6d254521
动态的盐
import hashlib username = 'xiaoyang' password = 'abcd123' hash_obj = hashlib.md5(username[::2].encode('utf-8')) # 每个用户不一样动态的加盐 hash_obj.update(password.encode('utf-8')) obj = hash_obj.hexdigest() print(obj) # 7adce56715fda64e0e0c425d9b6dc0c7
md5文件的校验
linux中一切皆文件: 文本文件,非文本文件,音频,视频,图片....
无论你下载的视频,还是软件(国外的软件),往往都会有一个md5值
def file_md5(path): ret = hashlib.sha256() with open(path,mode='rb') as f1: b1 = f1.read() ret.update(b1) return ret.hexdigest() result = file_md5('校验的文件名') print(result)
九、collections模块
namedtuple():命名元组
from collections import namedtuple rectangle = namedtuple('字符串用于描述rectangle类的类名', ['length', 'width']) r = rectangle(10, 5) # 通过属性访问元组的元素 print(r.length) print(r.width) # 输出 10 5
defaultdict():默认值字典,在取到没有的键时,会返回你定义的函数值,并添加进去
defaultdict 是内置的 dict 的子类
和 dict 的构造函数相比,只是在前面添加了一个参数: default_factory ,其余的参数和 dict 一样. 第一个参数指定的是一个函数名,用来表示当字典对象中出现了不存在的键时,对应的值初始值是如何计算.
正因为这个函数是获取值的,所以,对这个函数规定:不能有参数.默认情况下,第一个参数是None,意味着不存在的键对应的值为None.
注意:一旦使用 defaultdict 时,指定了不存在的键,则会引发两件事情:
1、调用第一个参数指定的函数得到默认值.
2、把返回值赋值给这个新键.
from collections import defaultdict def func(): return 'hello world' d = defaultdict(func,name='Andy',age=10) print(d['name']) # Andy print(d['haha']) # hello world print(d) # defaultdict(<function func at 0x000002C9A0D71E18>, {'name': 'Andy', 'age': 10,'haha': 'hello world'})
counter():计数器
用于统计可哈希对象的数量.
是dict的子类.一种特殊的字典.
它的键是可哈希对象,值是这个对象的个数统计信息.个数可以是手动指定的,也可以是自动计算出来的,并且可以是负数和0.
创建Counter对象.
c = Counter() # 创建空的计数器 c = Counter('abcdefabc') # 使用可迭代对象创建计数器 c = Counter({'A':1,'B':3}) # 使用字典创建计数器 c = Counter(A=1,B=3,C=0) # 手动初始化计数器
查看计数器的统计结果,和使用字典的方式相同:
from collections import Counter c = Counter('abcab') print(c) # Counter({'a': 2, 'b': 2, 'c': 1}) print(c['a']) # 2 print(c['b']) # 2 print(c['name']) # 0
Counter常用方法:
most_common[n]:显示数量最多的前几名。
from collections import Counter c = Counter('abcab') print(c.most_common(2)) # [('a', 2), ('b', 2)]
十、random模块
此模块提供了随机数获取方法
random.random( ):获取 [ 0.0, 1.0) 范围内的浮点数(伪随机数,有规律的)
import random print(random.random()) # 0.6291924643028873
random.randint(a, b):获取 [a, b] 范围内的一个整数
import random print(random.randint(3, 10)) # 5
random.uniform(a,b):获取 [a, b ) 范围内的浮点数
import random print(random.uniform(3, 10)) # 6.327077680813884
random.shuffle( x ):把参数指定的数据中的元素打乱洗。参数必须是可变的数据类型
import random ll = list(range(10)) random.shuffle(ll) print(ll) # [4, 8, 1, 6, 7, 9, 0, 3, 2, 5]
random.sample( x , k ):从 x 中随机抽取 k 个数据,组成一个列表返回
import random t = (1, 2, 3, 4, 5, 6, 7, 8, 9) ls = random.sample(t, len(t)) # 因为元组不可修改 print(ls) # [6, 4, 8, 1, 2, 7, 3, 9, 5]