Effective python(五):内置模块
1,考虑使用contextlib和with语句改写可复用的try/finally代码
with lock:print('lock is held')
相当于try:print('lock is held')
,finally:lock.release
,使用with可以避免繁琐的语句
- 开发者可以使用内置的contextlib模块的contextmanager修饰器来处理自己编写的对象和函数以支持with语句,这样做比标准写法更便捷,如果使用标准方式写,需要定义新类并提供__enter__和__exit__方法
from contextlib import contextmanager #上下文管理器
@contextmanager
def test():
print("初始化")
#可以在这里开启资源,如log等级上升
try:
print("with开始")
#如果有错误会通过yield弹出
yield
finally:
print("离开时释放资源") with test():
print("go")
- 可以在yield处弹出一个对象,通过as指定为一个局部变量,在with内可以对其进行交互
2,使用copyreg实现可靠的pickle操作
- python内置的pickle模块能将python对象转化为字节流,也能把字节反序列化为python对象,但pickle处理后的数据实际上就是一个程序,可能会混入恶意信息,对程序造成损坏,json产生的数据是一种安全的信息,只描述对象如何构成,不会造成额外风险,所以pickle处理的字节流不应该在未受信任的程序之间传播
- 例如定义一个
GameState
类,实例化为对象state=GameState()
包含玩家的当前游戏状态,生命,金币等等,玩家退出游戏的时候,将state直接写到一份文件里,游戏加载时读取with open(path,'wb') as f:
pickle.dump(state,f) with open(path,'rb') as f:
state_after=pickle.load(f)
print(state_after.__dict__)
- 如果类新增加了一些属性,但保存的对象仍然是旧的,那就需要使用copyreg了,先将类添加一个
__init__
构造器,通过传参的方式初始化属性,然后使用如下代码注册函数,序列化和反序列化仍然按照原来的方式使用即可def unpickle_game_state(kwargs):
return GameState(**kwargs)#返回State实例化 def pickle_game_state(game_state):#参数为State对象
kwargs=game_state.__dict__#获取其属性 #序列化封装需要返回反序列化的函数和参数
return unpickle_game_state,(kwargs,) copyreg.pickle(GameState,pickle_game_state)#注册pickle函数
- 使用版本号管理类,修改copyreg注册的pickle函数,在里面添加一个版本号的参数
kwargs['version]=2
,然后在反序列化函数中根据版本号对其进行操作,即可兼容版本
- 固定引入路径,若重构时,将类名修改或删除,那么反序列化的时候会出错,使用copyreg.pickle注册后,会自动指向unpickle函数,所以不用担心修改类名的问题,但如果没有使用copyreg注册,那么修改类名后反序列化就会报错
4,使用datetime模块处理本地时间而不是time模块
- time模块,内置的time模块中有一个名叫localtime的函数,可以把UNIX时间戳(timestamp即UTC时刻距离UNIX计时原点的秒数)转换为宿主计算机时区的当地时间,这个模块不够稳定,只能转换主机时区的时间,其它地区会出错,应该尽量不用,而是使用datetime模块
from time import localtime,strftime,strptime,mktime
time_format='%Y-%m-%d %H:%M:%S'
time_str=strftime(time_format,localtime(1407694710))
#将时间戳转换为当地时间
print(time_str) #将本地时间转化为UTC时间
#strptime解析时间字符串,mktime将本地时间转换为UNIX时间戳
print(mktime(strptime(strptime(time_str,time_format))))
- datetime模块
from datetime import datetime,timezone
from time import mktime #UTC时间转本地时间
now=datetime(2014,8,10,18,18,30)
now_utc=now.replace(tzinfo=timezone.utc)
#注意此处若想可靠的转换时区,还需要搭配pytz模块
now_local=now_utc.astimezone()#此处只包含UTC时区
print(now_local) #本地时间转UTC格式时间戳
time_str='2014-08-10 11:18:30'
time_format='%Y-%m-%d %H:%M:%S'
now=datetime.strptime(time_str,time_format)
time_tuple=now.timetuple()
utc_now=mktime(time_tuple)
print(time_tuple)
- 若要在不同时区之间执行可靠的转换操作,还需要搭配pytz模块使用
5,内置的数据结构与算法 (开发者不应该自己去重新实现,因为很难把他们写好)
- 双向队列,collections模块中的deque类,从该队列头部与尾部插入或移除一个元素,只有O(1)的时间复杂度
d=deque()
d.append(1)
x=d.popleft()
- 有序字典,collections模块中的OrderedDict类,它能够按照键的插入顺序,保留键值对在字典中的次序。标准字典是无序的,也就是说,在相同键值对的两个字典上迭代可能出现不同的迭代顺序
a=OrderedDict()
a['x']=1
- 默认值字典,collections模块中的defaultdict类,本例中用int函数创建字典,默认值为0
stats=defaultdict()
stats['my_counter']+=1
- 堆队列(优先队列),heapq模块中的heappush、heappop和nsmallest等函数,能够在标准的list中创建堆结构,时间复杂度O(logn),普通列表O(n)
a=[]
heappush(a,5)
heappush(a,3)
heappush(a,7)
heappush(a,4)
#总是能弹出优先级较高的元素,
#默认是越小元素优先级越高
print(heappop(a))
#即使调用sort后依然能保持堆结构
a.sort()
- 二分查找,bisect模块中的bisect_left函数,使用Index查找复杂度为O(n),二分为O(logn),注意:使用前列表应排好序,bisect搜索一百万个元素的列表,与index搜索包含14个元素的列表,所耗时间差不多
i_index = bisect_left(alist,number)
- 与迭代器有关的工具,itertools模块,可分为三大类
♦ 能够把迭代器连接起来的函数:
- chain:将多个迭代器按顺序连成一个迭代器
- cycle:无限重复某个迭代器中的各个元素
- tee:把一个迭代器拆分成多个平行的迭代器
- zip_longest:与内置的zip函数相似,可以应对不同长度的迭代器
♦ 能够从迭代器中过滤元素的函数:
- islice:在不复制的前提下,根据索引值来切割迭代器获取迭代器的一部分
- takewhile:在判定函数为True的时候,从迭代器逐个返回元素
- dropwhile:从判定函数初次为False的地方开始,逐个返回迭代器中的元素
- filterfalse:从迭代器中逐个返回能令判定函数为False的所有元素,效果与filter函数相反
♦ 能够把迭代器中的元素组合起来的函数:
- product:根据迭代器中的元素计算笛卡尔积(就是x*y),并返回。可以使用product改写深度嵌套的列表推导操作
- permutations:用迭代器中的元素构建长度为N的有序排列,例:
permutations('ABCD',2) # AB AC AD BA BC BD CA CB CD DA DB DC
- combination:用迭代器中的元素构建长度为N的无序组合,例:
combinations('ABCD', 2) # AB AC AD BC BD CD
备注:如果发现自己需要编写一段非常麻烦的迭代程序,应该花些时间看看itertools的文档看看有没有现成的工具可以用
6,在重视精度的场合,使用decimal模块中的Decimal类,该类默认提供28个小数位,以进行定点数学运算,有需要可以把精度提的更高
dec=Decimal('1.45')
在decimal之间进行计算会得到精确的结果,计算后的类型仍然是Decimal类型,print(dec)
- Decimal类提供quantize内置函数,它可以按照精度和舍入方式精确的调整数值
result=dec.quantize(Decimal('0.01'),rounding=ROUND_UP)
,print(result)
- 若要使用精度不受限的方式表达有理数,那么可以考虑使用Fraction类,包含在内置的fractions模块里
7,学会使用pypi,Python中央仓库:https://pypi.python.org
- 如果碰到不熟悉的编程难题,应该去PyPI里看看别人的代码
- pip3安装python3版本的软件包,pip安装python2版本的软件包
Effective python(五):内置模块的更多相关文章
- 《Effective Python:编写高质量Python代码的59个有效方法》读书笔记(完结)
Effective Python 第1章 用Pythonic方式来思考 be pythonic 遵守pep8 python3有两种字符序列类型:bytes(原始的字节)和str(Unicode字符). ...
- Effective Python之编写高质量Python代码的59个有效方法
这个周末断断续续的阅读完了<Effective Python之编写高质量Python代码 ...
- 【Python五篇慢慢弹】快速上手学python
快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...
- 【Python五篇慢慢弹】数据结构看python
数据结构看python 作者:白宁超 2016年10月9日14:04:47 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...
- 【Python五篇慢慢弹(3)】函数修行知python
函数修行知python 作者:白宁超 2016年10月9日21:51:52 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...
- 【Python五篇慢慢弹(4)】模块异常谈python
模块异常谈python 作者:白宁超 2016年10月10日12:08:31 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondo ...
- 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸
类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...
- Effective Python 中文版
如题,博主正在翻译一本Python相关的书. 图为Python作者. [美]Brett Slatkin的名作. Effective Python: 59 Specific Ways to Write ...
- Python常用内置模块之xml模块
xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.从结构上,很像HTML超文本标记语言.但他们被设计的目的是不同的,超文本标记语言被设计用来显示 ...
- [Effective Python] 用Pythonic方式来思考
Effective Python chap.1 用Pythonic方式来思考 Pythonic: 一门语言的编程习惯是由用户来确立的. 1. 确认自己所使用的Python版本 2. 遵循PEP8风格指 ...
随机推荐
- e代驾推出新产品“e代喝”,能否实现前者的社交梦?
近日,关于e代驾推出e代喝的新闻不断出现在各大媒体的新闻报道之中,看似好像是替人排扰解难的征服酒局的又一利器.但事实真的如此吗?首先要弄清楚的,是目前e代驾在行业中的处境.作为代驾行业的先驱者,e代驾 ...
- Dubbo之心跳机制 · 房东的小黑
在网络传输中,怎么确保通道连接的可用性是一个很重要的问题,简单的说,在网络通信中有客户端和服务端,一个负责发送请求,一个负责接收请求,在保证连接有效性的背景下,这两个物体扮演了什么角色,心跳机制能有效 ...
- Spring aop(1)--- 寻找切面和代理对象执行流程源码分析
1.基于注解,首先我们是通过@EnableAspectJAutoProxy()这个注解开起AOP功能,这个注解会导入AspectJAutoProxyRegistrar组件从而将AnnotationAw ...
- 在线选题系统完善篇(PHP)
第一篇: 选题在线提交系统(html+JS+PHP) 这是当时根据需求做的一个简单的版本,只能适用于这一个场景,而且题目等一系列数据都不能改.然后结束后,我又对重新写了一个有后台管理的选题系统.相对于 ...
- iMX287A多种方法实现流水灯效果
目录 1.流水灯在电子电路中的地位 2.硬件电路分析 3.先点个灯吧 4.shell脚本实现流水灯 5.ANSI C文件操作实现流水灯 6.Linux 系统调用实现流水灯 @ 1.流水灯在电子电路中的 ...
- 位运算基础(Uva 1590,Uva 509题解)
逻辑运算 规则 符号 与 只有1 and 1 = 1,其他均为0 & 或 只有0 or 0 = 0,其他均为1 | 非 也就是取反 ~ 异或 相异为1相同为0 ^ 同或 相同为1相异为0,c中 ...
- Linux进程操作记录
关于Gunicorn如何终止进程: 1.用进程树显示主进程PID: pstree -ap | grep gunicorn 2.如果有daemon进程无法用kill -9删除(可能是因为daemon屏蔽 ...
- Subsequence POJ - 3061
Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22040 Accepted: 9404 Desc ...
- Ansible-安装配置
主机规划 主机名称 操作系统版本 内网IP 外网IP(模拟) 安装软件 ansi-manager CentOS7.5 172.16.1.180 10.0.0.180 ansible ansi-hapr ...
- Core + Vue 后台管理基础框架0——开篇
1.背景 最近,打算新开个项目,鉴于团队技术栈,选型.net core + vue,前后端分离.本打算捡现成的轮子的,github上大致逛了逛,总发现这样那样的不太适合心中那些“完美实践”,例如:Ab ...