一、struct:打包
struct模块中最主要的三个函数式pack()、unpack()、calcsize()。
- pack(fmt, v1, v2, …) —— 根据所给的fmt描述的格式将值v1,v2,…转换为一个字符串。
- unpack(fmt, bytes) —— 根据所给的fmt描述的格式将bytes反向解析出来,返回一个元组。
- calcsize(fmt) —— 根据所给的fmt描述的格式返回该结构的大小。
示例代码
import struct
pack_num = struct.pack('i', 126)
print('pack_string',pack_num,len(pack_num))
unpack_num = struct.unpack('i', pack_num)
print('unpack_string',unpack_num)
# pack_string b'~\x00\x00\x00' 4
# unpack_string (126,)
print("len: ", struct.calcsize('i')) # len: 4
print("len: ", struct.calcsize('ii')) # len: 8
print("len: ", struct.calcsize('f')) # len: 4
print("len: ", struct.calcsize('ff')) # len: 8
print("len: ", struct.calcsize('s')) # len: 1
print("len: ", struct.calcsize('ss')) # len: 2
print("len: ", struct.calcsize('d')) # len: 8
print("len: ", struct.calcsize('dd')) # len: 16
print("len: ", struct.calcsize('B')) # len: 1
print("len: ", struct.calcsize('!BH')) # len: 3
print("len: ", struct.calcsize('!BQ')) # len: 9
二、tqdm: 进度条
In [1]: from tqdm import tqdm
In [2]: import time
In [3]: a = 0
In [4]: for i in tqdm(range(10)):
...: a += i
...: time.sleep(1)
...:
10%|████████ | 1/10 [00:01<00:09, 1.
20%|████████████████▏ | 2/10 [00:02<0
30%|████████████████████████▎ | 3/10
40%|████████████████████████████████▍
50%|████████████████████████████████████████▌
60%|████████████████████████████████████████████████▌
70%|████████████████████████████████████████████████████████
80%|████████████████████████████████████████████████████████
90%|████████████████████████████████████████████████████████
100%|████████████████████████████████████████████████████████
100%|████████████████████████████████████████████████████████
████████████████████████| 10/10 [00:10<00:00, 1.00s/it]
三、itertools
- itertools:为高效循环而创建迭代器的函数
本模块实现一系列 iterator ,这些迭代器受到APL,Haskell和SML的启发。为了适用于Python,它们都被重新写过。本模块标准化了一个快速、高效利用内存的核心工具集,这些工具本身或组合都很有用。它们一起形成了“迭代器代数”,这使得在纯Python中有可能创建简洁又高效的专用工具。以下为使用示例:
# -*- coding: utf-8 -*-
"""
Datetime: 2020/06/25
Author: Zhang Yafei
Description: itertools 包
"""
def itertools_count():
"""
无穷的迭代器 count(start,[step])
count 接受两个参数
start:循环开始的数字
step:循环中的间隔
"""
from itertools import count
c = count(0, 2)
v = next(c)
while v < 10:
v = next(c)
print(v, end=',')
def itertools_cycle():
"""
无穷迭代器 cycle()
cycle就是一while True,无限循环里面的数字。
"""
from itertools import cycle
c = cycle('ABCD')
for i in range(10):
print(next(c), end=',')
def itertools_repeat():
"""
repeat(elem,[n])
重复迭代elem,n次
"""
from itertools import repeat
r = repeat(1, 3)
for i in range(3):
print(next(r), end=',')
def itertools_accumulate():
"""
迭代器 accumulate()
accumulate(p,[func])
使用func的函数对迭代对象p进行累积。
"""
from itertools import accumulate
test_list = [i for i in range(1, 11)]
for i in accumulate(test_list): # 默认是operator.add
print(i, end=',')
print()
for i in accumulate(test_list, lambda x, y: x * y): # operator.mul
print(i, end=',')
def itertools_chain():
"""
迭代器 chain()
chain()中可以放多个迭代对象,然后一一迭代出来。
"""
from itertools import chain
ch = chain([1, 2, 3], {4: 4, 5: 5}, {6, 7, 8}, (9,), [10, [11, 12]])
for i in ch:
print(i)
def itertools_chain_from_iterable():
"""
迭代器 chain.from_iterable()
跟chain不同的地方在于:
chain: 可以接受多个迭代对象
chain.from_iterable():可以接受一个可以产生迭代对象的迭代器
"""
from itertools import chain
def gen_iterables():
for i in range(10):
yield range(i)
for i in chain.from_iterable(gen_iterables()):
print(i)
def itertools_compress():
"""
迭代器 compress
compress(data, selectors)
这是就是看下这个就知道了s是selectors中的元素。
(d[0] if s[0]), (d[1] if s[1]), ...
"""
from itertools import compress
print(list(compress(['A', 'B', 'C', 'D'], [0, 1, 1, 1])))
def itertools_dropwhile():
"""
迭代器 dropwhile()
dropwhile(pred, seq)
循环开始的条件是,直到遇到第一次不满足pred条件的情况,才开始遍历。
"""
from itertools import dropwhile
l = [1, 7, 6, 3, 8, 2, 10]
print(list(dropwhile(lambda x: x < 3, l)))
def itertools_groupby():
"""
groupby
这个感觉有点像sql中的group_by。可以对字符串,列表等进行分组。
返回键和,组里的内容
"""
from itertools import groupby
# 对字符串进行分组
for k, g in groupby('11111234567'):
print(k, list(g))
d = {1: 1, 2: 2, 3: 2}
# 按照字典value来进行分组
for k, g in groupby(d, lambda x: d.get(x)):
print(k, list(g))
def itertools_slice():
"""
islice
这个就是对迭代对象进行切割,不支持负数,有点像range(1, 10, 2)
"""
from itertools import islice
print(list(islice('ABCDEFG', 2, 3, None)))
def itertools_zip_longest():
"""
zip_longest
这个和zip很像,不同地方在于:
zip结束取决于里面最短的迭代对象
zip_longest结束取决于里面最长的迭代对象
:return:
"""
from itertools import zip_longest
for x, y in zip_longest([1, 2, 3], [1, 2]):
print(x, y)
for x, y in zip([1, 2, 3], [1, 2]):
print(x, y)
def itertools_product():
"""
product
相当于 嵌套的for
排列组合迭代器 product 嵌套的for
"""
from itertools import product
for i, j in product([1, 2, 3], [4, 5]):
print(i, j)
def itertools_permutations():
"""
全排列,比如输出123的全部情况。(1,2,3),(1,3,2)…
"""
from itertools import permutations
print(list(permutations('123')))
def itertools_combinations():
"""
combinations(p,r)
从p中找出所有长度为r的排列情况… 有顺序
:return:
"""
from itertools import combinations
print(list(combinations([1, 2, 3], 2)))
print(list(combinations('ABCD', 2)))
def itertools_combinations_with_replacement():
"""combinations_with_replacement()
从p中找出所有长度为r的排列情况,有顺序,但包括自身就是会重复的意思。
"""
from itertools import combinations_with_replacement
print(list(combinations_with_replacement('ABCD', 2)))
# AA AB AC AD BB BC BD CC CD DD
if __name__ == '__main__':
itertools_count()
itertools_cycle()
itertools_repeat()
itertools_accumulate()
itertools_chain()
itertools_chain_from_iterable()
itertools_compress()
itertools_dropwhile()
itertools_groupby()
itertools_slice()
itertools_zip_longest()
itertools_product()
itertools_combinations()
itertools_combinations_with_replacement()
itertools_permutations()
四、collections
"""
namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。
这样一来,我们用namedtuple可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。
"""
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
print(p.x)
print(p.y)
1 = [Point(i, j) for i in range(5) for j in range(5)]
for p in l1:
print(p.x, p.y)
Circle = namedtuple('Circle', ['x', 'y', 'r'])
"""
deque
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
"""
from collections import deque
q = deque(['a', 'b', 'c'])
q.append('x')
q.appendleft('y')
print(q)
"""
defaultdict
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
"""
from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
dd['key1'] # key1存在
dd['key2'] # key2不存在,返回默认值
"""
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict:
"""
from collections import OrderedDict
d = dict([('a', 1), ('b', 2), ('c', 3)])
d # dict的Key是无序的
od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(od) # OrderedDict的Key是有序的
# 注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:
"""
Counter
Counter是一个简单的计数器,例如,统计字符出现的个数:
"""
from collections import Counter
c = Counter('programming')
print(c)
五、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 输出用于分割文件路径的字符串
- 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所指向的文件或者目录的最后修改时间
六、sys
- sys.argv 命令行参数List,第一个元素是程序本身路径
- sys.exit(n) 退出程序,正常退出时exit(0)
- sys.version 获取Python解释程序的版本信息
- sys.maxint 最大的Int值
- sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
- sys.platform 返回操作系统平台名称
- sys.stdout.write(‘please:’)
- val = sys.stdin.readline()[:-1]
七、hashlib
hashlib 是一个提供了一些流行的hash算法的 Python 标准库.其中所包括的算法有 md5, sha1, sha224, sha256, sha384, sha512. 另外,模块中所定义的 new(name, string=”) 方法可通过指定系统所支持的hash算法来构造相应的hash对象.
from hashlib import md5, sha1, sha224, sha256, sha384, sha512
from pprint import pprint
import hashlib
hash_funcs = [md5, sha1, sha224, sha256, sha384, sha512]
def hash_show(s):
result = []
for func in hash_funcs:
s_hash_obj = func(s.encode())
s_hash_hex = s_hash_obj.hexdigest()
result.append((s_hash_obj.name, s_hash_hex, len(s_hash_hex)))
return result
if __name__ == '__main__':
# 1.各hashlib算法的使用案例
s = 'hello python'
rs = hash_show(s)
pprint(rs)
# 2.md5的使用案例
m1 = md5() # 构造hash对象
m1.update('hello'.encode())
m1.update(' '.encode())
m1.update('python'.encode())
m2 = md5('hello python'.encode())
print(m1.hexdigest() == m2.hexdigest())
# 两种方式的效果相同
# 3.使用 new(name, string=”) 构造新的哈系对象
h = hashlib.new('ripemd160', 'hello python'.encode())
# ripemd160是一个160位的hash算法. ripemd系列算法基于md4, md5.
print(h.hexdigest(),len(h.hexdigest()))
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
import hashlib
# ######## md5 ########
hash = hashlib.md5('898oaFs09f')
hash.update('admin')
print(hash.hexdigest())
除此之外,python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
import hmac
h = hmac.new('zhangyafei')
h.update('hellowo')
print(h.hexdigest())
八、json和pickle
用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
json
- json.dumps (obj):将 python 对象编码转化为 json 字符串
- json.loads (str):将 json 格式转化为 python dict格式
- json.dump(f, obj):dump 和 dumps 的功能一样,将 dict 转化为 str 的格式,然后存入文件中。
- json.load(f) :load 和 loads 的功能一样,从文件中读取 str 格式并将其转化为json。
示例
import json
data = {
'Citizen_Wang':1,
'Always fall in love':2,
'with neighbours.':3
}
json_str = json.dumps(data)
#print('Python 原始数据是:', data)
#print('json 对象:',json_str)
print(type(data))
print(type(json_str))
date2 = json.loads(json_str)
print(type(json_str))
print(type(date2))
#转化后的 json_str 是一个字符串类型,可以使用 enumerate 来查看一下 json_str 字符串的索引值和对应值。
file = open('2.txt', 'wb')
print(type(file))
json.dump(data, file)
json.dump(json_str, file)
"""
json字符串
1.将json字符串json.loads转化为字典
2.用key值提取value
"""
json_str = '{"demo":{"demo1":{"demo2":{"demo3":"result"}}}}'
print(type(json_str))
str1 = json.loads(json_str)
print(type(str1))
str1['demo']['demo1']['demo2']['demo3']
#load 在读取的时候,只需要文件对象一个参数即可。而 dump 在使用的时候,需要 python 对象作为第一个传入参数,文件对象作为第二个传入参数。
"""
小结:
json数据类型的字符串必须用单引号包起来,里面是双引号
dump 或 dumps, 把其他对象或者格式,转化为 json str 格式,
dumps 用来处理字符串,dump 用来处理文件。
load 或 loads ,把 json str 格式转化成其他格式,
loads 用来处理字符串,load 用来处理文件。
注:json.loads(response.text) == response.json()
"""
pickle
pickle可以存储什么类型的数据呢?
所有python支持的原生类型:布尔值,整数,浮点数,复数,字符串,字节,None。由任何原生类型组成的列表,元组,字典和集合, 函数,类,类的实例
pickle模块可能出现三种异常:
- PickleError:封装和拆封时出现的异常类,继承自Exception
- PicklingError: 遇到不可封装的对象时出现的异常,继承自PickleError
- UnPicklingError: 拆封对象过程中出现的异常,继承自PickleError
示例
"""dumps"""
import pickle
list = ["aa","bb","cc"]
#4 # dumps 将数据通过特殊的形式转换为只有python语言认识的字符串
pickle_str = pickle.dumps(list)
print(pickle_str)
"""
loads
将pickle数据转换为python的数据结构
"""
py_str = pickle.loads(pickle_str)
print(py_str)
"""dump功能
dump 将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件
"""
with open('pickle.txt', 'wb') as f:
pickle.dump(list, f)
"""
load: 从数据文件中读取数据,并转换为python的数据结构
"""
with open('pickle.txt', 'rb') as f:
data = pickle.load(f)
print(data)
json和pickle的区别
- pickle可以在python之间进行交互
- json可以实现python与不同开发语言的交互
- pickle可以序列化python中的任何数据类型
- json只能序列化python中的常归数据类型(列表等)
- pickle序列化后的对象不可读
- json序列化后的对象是可读的
九、logging
日志:用来记录用户行为 或者 代码的执行的过程。用处:一键控制
- 拍错的时候需要打印很多东西来帮助我排错
- 严重的错误记录下来
- 有一些用户行为,有没有错都要记录下来
import logging
logging.debug('debug message') #低级别的 排错信息
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message') #高级别的
basicConfig
import logging
# basicconfig 简单 能做的事情相对少
#中文乱码问题
#不能同时往屏幕和文件输出
# 配置log对象 稍微有点复杂,能做的事相对多
"""
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
只有大于当前日志等级的操作才会被记录。
"""
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',
datefmt='%Y/%m/%d %H:%M:%S',
filename='test.log',
filemode='w',
)
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
"""
logger对象
# logger对象配置
# 程序的充分解耦
# 让程序变得高可定制性
# 5种级别的日志记录模式
# 两种配置方式basicconfig,log对象
import logging
logger = logging.getLogger()
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('log.log',encoding='utf-8')
# 再创建一个handler,用于输出到控制台
sh = logging.StreamHandler() #创建一个屏幕控制对象
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
formatter2 = logging.Formatter('%(asctime)s - %(name)s - %(levelno)s - %(levelname)s - [line-%(lineno)d] - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')
fh.setLevel(logging.DEBUG)
#文件操作符 和 格式 关联
fh.setFormatter(formatter)
sh.setFormatter(formatter2)
#logger对象和文件操作符关联
logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
logger.addHandler(sh)
logger.debug('logger debug message') #细节
logger.info('logger info message') #正常信息
logger.warning('警告信息') #不影响程序,警告信息
logger.error('logger error message') #错误信息
logger.critical('logger critical message') #高级别的,严重错误信息
logger类
class Logger(object):
"""
logger对象:打印日志
"""
def __init__(self):
self.run_log_file = RUN_LOG_FILE
self.error_log_file = ERROR_LOG_FILE
self.run_log = None
self.error_log = None
self.initialize_run_log()
self.initialize_error_log()
@staticmethod
def check_path_exist(log_abs_file):
log_path = os.path.split(log_abs_file)[0]
if not os.path.exists(log_path):
os.mkdir(log_path)
def initialize_run_log(self):
self.check_path_exist(self.run_log_file)
fh = logging.FileHandler(self.run_log_file, 'a', encoding='utf-8')
sh = logging.StreamHandler()
# fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s : %(message)s")
# fh.setFormatter(fmt)
# sh.setFormatter(fmt)
logger1 = logging.Logger('run_log', level=logging.INFO)
logger1.addHandler(fh)
logger1.addHandler(sh)
self.run_logger = logger1
def initialize_error_log(self):
self.check_path_exist(self.error_log_file)
fh = logging.FileHandler(self.error_log_file, 'a', encoding='utf-8')
sh = logging.StreamHandler()
# fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s : %(message)s")
# fh.setFormatter(fmt)
# sh.setFormatter(fmt)
logger1 = logging.Logger('error_log', level=logging.ERROR)
logger1.addHandler(fh)
logger1.addHandler(sh)
self.error_logger = logger1
def log(self, message, mode=True):
"""
写入日志
:param message: 日志信息
:param mode: True表示运行信息,False表示错误信息
:return:
"""
if mode:
self.run_logger.info(message)
else:
self.error_logger.error(message)
logger = Logger()
logger.log(content,False)
十:时间模块
参考:https://www.cnblogs.com/zhangyafei/p/9836850.html
十一、re正则
参考:https://www.cnblogs.com/zhangyafei/articles/10113408.html
十二、random
import random
# 用于生成一个0到1的随机浮点数:0<=n<=1
random.random()
# random.uniform(a,b)用于生成一个指定范围内的随机浮点数, 两个参数一个是上限,一个是下限
random.uniform(10,20)
# random.randint(a,b),用于生成一个指定范围内的随机整数
random.randint(12,20)
# random.randrange(start,end,step)起始值,结束值,步长,从指定范围内找一个随机数
list(range(60,100,2))
random.randrange(10,100,2)
# random.choice()从序列(有序类型:;list,tuple,dict,string)里面获取一个随机元素
random.choice(('Tuple','list','dict','string'))
# random.shuffle(x[,random]),用于将一个列表中的元素打乱
p = ['python','is','powerful','simple','and','so on……']
random.shuffle(p)
p
# random.sample(sequence,k),从指定序列中随机获取指定长度的片段,sample函数不会修改原有序列
list_1 = [1,2,3,4,5,6,7,8,9,10]
slice_1 = random.sample(list_1,6)
print(slice_1)
print(list_1)
# 随机选取0到100的偶数
random.randrange(0,101,2)
# 随机字符
random.choice('ascdefg$%^WE#$*')
# 多个字符中选取特定数量的字符
random.sample('ascdrfghijk',3)
# 多个字符中选取特定数量的字符组成新字符串
"".join(random.sample(['a','b','c','d','e','f','g'],3))
# 随机选取字符串
random.choice(['apple','pear','peach','orange','lemon'])
# 洗牌
items = [1,2,3,4,5,6]
items = list(range(1,53))
random.shuffle(items)
items
本节讲了十二个常用的内置标准库,当然这还不是python标准库的全部,其他的内容将会在之后的内容中补充以及你自己去发现,本节到此结束。