第四篇:常用模块

Python常用模块

time模块

import time

时间戳

  时间戳(timestamp):时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。

time_stamp = time.time()
print(time_stamp, type(time_stamp))
1552551519.291029 

格式化时间

  格式化的时间字符串(format string):格式化时间表示的是普通的字符串格式的时间。

format_time = time.strftime("%Y-%m-%d %X")
print(format_time, type(format_time))
2019-03-07 16:22:11 

结构化时间

  结构化的时间(struct time):struct_time元组共有9个元素共九个元素,分别为(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)

print('本地时区的struct_time:\n{}'.format(time.localtime()))
print('UTC时区的struct_time:\n{}'.format(time.gmtime()))
本地时区的struct_time:
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=7, tm_hour=16, tm_min=22, tm_sec=11, tm_wday=3, tm_yday=66, tm_isdst=0)
UTC时区的struct_time:
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=7, tm_hour=8, tm_min=22, tm_sec=11, tm_wday=3, tm_yday=66, tm_isdst=0)
# 结构化时间的基准时间
print(time.localtime(0))
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
# 结构化时间的基准时间上增加一年时间
print(time.localtime(3600*24*365))
time.struct_time(tm_year=1971, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=1, tm_isdst=0)

不同格式时间的转换

  如上图所示,我们总能通过某些方法在结构化时间-格式化时间-时间戳三者之间进行转换,下面我们将用代码展示如何通过这些方法转换时间格式。

# 结构化时间
now_time = time.localtime()
print(now_time)
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=7, tm_hour=16, tm_min=22, tm_sec=11, tm_wday=3, tm_yday=66, tm_isdst=0)
# 把结构化时间转换为时间戳格式
print(time.mktime(now_time))
1551946931.0
# 把结构化时间转换为格式化时间
# %Y年-%m月-%d天 %X时分秒=%H时:%M分:%S秒
print(time.strftime("%Y-%m-%d %X", now_time))
2019-03-07 16:22:11
# 把格式化时间化为结构化时间,它和strftime()是逆操作
print(time.strptime('2013-05-20 13:14:52', '%Y-%m-%d %X'))
time.struct_time(tm_year=2013, tm_mon=5, tm_mday=20, tm_hour=13, tm_min=14, tm_sec=52, tm_wday=0, tm_yday=140, tm_isdst=-1)
# 把结构化时间表示为这种形式:'Sun Jun 20 23:21:05 1993'。
print(time.asctime())
Thu Mar  7 16:22:11 2019
# 如果没有参数,将会将time.localtime()作为参数传入。
print(time.asctime(time.localtime()))
Thu Mar  7 16:22:11 2019
# 把一个时间戳转化为time.asctime()的形式。
print(time.ctime())
Thu Mar  7 16:22:11 2019
# 如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
print(time.ctime(time.time()))
Thu Mar  7 16:22:11 2019

其他用法

# 推迟指定的时间运行,单位为秒
start = time.time()
time.sleep(3)
end = time.time()

print(end-start)
3.0005428791046143

datetime模块

# datetime模块可以看成是时间加减的模块
import datetime
# 返回当前时间
print(datetime.datetime.now())
2019-03-07 16:22:14.544130
print(datetime.date.fromtimestamp(time.time()))
2019-03-07
# 当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(3))
2019-03-10 16:22:14.560599
# 当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(-3))
2019-03-04 16:22:14.568473
# 当前时间-3小时
print(datetime.datetime.now() + datetime.timedelta(hours=3))
2019-03-07 19:22:14.575881
# 当前时间+30分钟
print(datetime.datetime.now() + datetime.timedelta(minutes=30))
2019-03-07 16:52:14.585432
# 时间替换
c_time = datetime.datetime.now()
print(c_time.replace(minute=20, hour=5, second=13))
2019-03-07 05:20:13.595493

random模块

import random
# 大于0且小于1之间的小数
print(random.random())
0.25435092120631386
# 大于等于1且小于等于3之间的整数
print(random.randint(1, 3))
2
# 大于等于1且小于3之间的整数
print(random.randrange(1, 3))
1
# 大于1小于3的小数,如1.927109612082716
print(random.uniform(1, 3))
2.718804989532962
# 列表内的任意一个元素,即1或者‘23’或者[4,5]
print(random.choice([1, '23', [4, 5]]))
1
# random.sample([], n),列表元素任意n个元素的组合,示例n=2
print(random.sample([1, '23', [4, 5]], 2))
[[4, 5], '23']
lis = [1, 3, 5, 7, 9]
# 打乱l的顺序,相当于"洗牌"
random.shuffle(lis)
print(lis)
[1, 3, 9, 7, 5]

os模块

  os模块负责程序与操作系统交互。

方法 详解
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: (‘.’)
os.pardir 获取当前目录的父目录字符串名:(‘..’)
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.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->’nt’; Linux->’posix’
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
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的大小

sys模块

  sys模块负责程序与Python解释器进行交互。

方法 详解
sys.argv 命令行参数List,第一个元素是程序本身路径
sys.modules.keys() 返回所有已经导入的模块列表
sys.exc_info() 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n) 退出程序,正常退出时exit(0)
sys.hexversion 获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.maxunicode 最大的Unicode值
sys.modules 返回系统导入的模块字段,key是模块名,value是模块
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
sys.stdout 标准输出
sys.stdin 标准输入
sys.stderr 错误输出
sys.exc_clear() 用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix 返回平台独立的python文件安装的位置
sys.byteorder 本地字节规则的指示器,big-endian平台的值是’big’,little-endian平台的值是’little’
sys.copyright 记录python版权相关的东西
sys.api_version 解释器的C的API版本

json和pickle模块

序列化

  把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening。

序列化的优点:

  1. 持久保存状态:内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。但是在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。
  2. 跨平台数据交互:序列化时不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

json

  Json序列化并不是python独有的,json序列化在java等语言中也会涉及到,因此使用json序列化能够达到跨平台传输数据的目的。

json数据类型和python数据类型对应关系表

Json类型 Python类型
{} dict
[] list
"string" str
520.13 int或float
true/false True/False
null None

json模块序列化和反序列化的一个过程如下图所示

import json
struct_data = {'name': 'json', 'age': 23, 'sex': 'male'}
print(struct_data, type(struct_data))
{'name': 'json', 'age': 23, 'sex': 'male'} 
data = json.dumps(struct_data)
print(data, type(data))
{"name": "json", "age": 23, "sex": "male"} 
# 注意:无论数据是怎样创建的,只要满足json格式(如果是字典,则字典内元素都是双引号),就可以json.loads出来,不一定非要dumps的数据才能loads
data = json.loads(data)
print(data, type(data))
{'name': 'json', 'age': 23, 'sex': 'male'} 
# 序列化
with open('Json序列化对象.json', 'w') as fw:
    json.dump(struct_data, fw)
# 反序列化
with open('Json序列化对象.json') as fr:
    data = json.load(fr)
print(data)
{'name': 'json', 'age': 23, 'sex': 'male'}

pickle

  Pickle序列化和所有其他编程语言特有的序列化问题一样,它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,即不能成功地反序列化也没关系。但是pickle的好处是可以存储Python中的所有的数据类型,包括对象,而json不可以。

pickle模块序列化和反序列化的过程如下图所示

import pickle
struct_data = {'name': 'json', 'age': 23, 'sex': 'male'}
print(struct_data, type(struct_data))
{'name': 'json', 'age': 23, 'sex': 'male'} 
data = pickle.dumps(struct_data)
print(data, type(data))
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00jsonq\x02X\x03\x00\x00\x00ageq\x03K\x17X\x03\x00\x00\x00sexq\x04X\x04\x00\x00\x00maleq\x05u.' 
data = pickle.loads(data)
print(data, type(data))
{'name': 'json', 'age': 23, 'sex': 'male'} 
# 序列化(注意:pickle模块需要使用二进制存储,即'wb'模式存储)
with open('Pickle序列化对象.pkl', 'wb') as fw:
    pickle.dump(struct_data, fw)
# 反序列化
with open('Pickle序列化对象.pkl', 'rb') as fr:
    pickle = pickle.load(fr)
print(data)
{'name': 'json', 'age': 23, 'sex': 'male'}

hashlib模块

hash是什么

  hash是一种算法(Python3.版本里使用hashlib模块代替了md5模块和sha模块,主要提供 SHA1、SHA224、SHA256、SHA384、SHA512、MD5 算法),该算法接受传入的内容,经过运算得到一串hash值。

hash值的特点:

  1. 只要传入的内容一样,得到的hash值一样,可用于非明文密码传输时密码校验
  2. 不能由hash值返解成内容,即可以保证非明文密码的安全性
  3. 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的,可以用于对文本的哈希处理

  hash算法其实可以看成如下图所示的一座工厂,工厂接收你送来的原材料,经过加工返回的产品就是hash值

import hashlib
m = hashlib.md5()

m.update('hello'.encode('utf8'))
print(m.hexdigest())
5d41402abc4b2a76b9719d911017c592
m.update('hash'.encode('utf8'))
print(m.hexdigest())
97fa850988687b8ceb12d773347f7712
m2 = hashlib.md5()
m2.update('hellohash'.encode('utf8'))
print(m2.hexdigest())
97fa850988687b8ceb12d773347f7712
m3 = hashlib.md5()
m3.update('hello'.encode('utf8'))
print(m3.hexdigest())
5d41402abc4b2a76b9719d911017c592

撞库破解hash算法加密

  hash加密算法虽然看起来很厉害,但是他是存在一定缺陷的,即可以通过撞库可以反解,如下代码所示。

import hashlib

# 假定我们知道hash的微信会设置如下几个密码
pwd_list = [
    'hash3714',
    'hash1313',
    'hash94139413',
    'hash123456',
    '123456hash',
    'h123ash',
]

def make_pwd_dic(pwd_list):
    dic = {}
    for pwd in pwd_list:
        m = hashlib.md5()
        m.update(pwd.encode('utf-8'))
        dic[pwd] = m.hexdigest()
    return dic

def break_code(hash_pwd, pwd_dic):
    for k, v in pwd_dic.items():
        if v == hash_pwd:
            print('hash的微信的密码是===>\033[46m%s\033[0m' % k)

hash_pwd = '0562b36c3c5a3925dbe3c4d32a4f2ba2'
break_code(hash_pwd, make_pwd_dic(pwd_list))
hash的微信的密码是===>hash123456

  为了防止密码被撞库,我们可以使用python中的另一个hmac 模块,它内部对我们创建key和内容做过某种处理后再加密。

如果要保证hmac模块最终结果一致,必须保证:

  1. hmac.new括号内指定的初始key一样
  2. 无论update多少次,校验的内容累加到一起是一样的内容
import hmac

# 注意hmac模块只接受二进制数据的加密
h1 = hmac.new(b'hash')
h1.update(b'hello')
h1.update(b'world')
print(h1.hexdigest())
905f549c5722b5850d602862c34a763e
h2 = hmac.new(b'hash')
h2.update(b'helloworld')
print(h2.hexdigest())
905f549c5722b5850d602862c34a763e
h3 = hmac.new(b'hashhelloworld')
print(h3.hexdigest())
a7e524ade8ac5f7f33f3a39a8f63fd25

logging模块

联系管理员微信tutu19192010,注册账号

上一篇
下一篇
Copyright © 2022 Egon的技术星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术