1,考虑使用contextlib和with语句改写可复用的try/finally代码

  1. with lock:print('lock is held')相当于try:print('lock is held')finally:lock.release,使用with可以避免繁琐的语句
  1. 开发者可以使用内置的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")
  1. 可以在yield处弹出一个对象,通过as指定为一个局部变量,在with内可以对其进行交互

2,使用copyreg实现可靠的pickle操作

  1. python内置的pickle模块能将python对象转化为字节流,也能把字节反序列化为python对象,但pickle处理后的数据实际上就是一个程序,可能会混入恶意信息,对程序造成损坏,json产生的数据是一种安全的信息,只描述对象如何构成,不会造成额外风险,所以pickle处理的字节流不应该在未受信任的程序之间传播
  1. 例如定义一个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__)
  1. 如果类新增加了一些属性,但保存的对象仍然是旧的,那就需要使用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函数
  1. 使用版本号管理类,修改copyreg注册的pickle函数,在里面添加一个版本号的参数kwargs['version]=2,然后在反序列化函数中根据版本号对其进行操作,即可兼容版本
  1. 固定引入路径,若重构时,将类名修改或删除,那么反序列化的时候会出错,使用copyreg.pickle注册后,会自动指向unpickle函数,所以不用担心修改类名的问题,但如果没有使用copyreg注册,那么修改类名后反序列化就会报错

4,使用datetime模块处理本地时间而不是time模块

  1. 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))))
  1. 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)
  1. 若要在不同时区之间执行可靠的转换操作,还需要搭配pytz模块使用

5,内置的数据结构与算法 (开发者不应该自己去重新实现,因为很难把他们写好)

  1. 双向队列,collections模块中的deque类,从该队列头部与尾部插入或移除一个元素,只有O(1)的时间复杂度
    d=deque()
    d.append(1)
    x=d.popleft()
  1. 有序字典,collections模块中的OrderedDict类,它能够按照键的插入顺序,保留键值对在字典中的次序。标准字典是无序的,也就是说,在相同键值对的两个字典上迭代可能出现不同的迭代顺序
    a=OrderedDict()
    a['x']=1
  1. 默认值字典,collections模块中的defaultdict类,本例中用int函数创建字典,默认值为0
    stats=defaultdict()
    stats['my_counter']+=1
  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()
  1. 二分查找,bisect模块中的bisect_left函数,使用Index查找复杂度为O(n),二分为O(logn),注意:使用前列表应排好序,bisect搜索一百万个元素的列表,与index搜索包含14个元素的列表,所耗时间差不多
    i_index = bisect_left(alist,number)
  1. 与迭代器有关的工具,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个小数位,以进行定点数学运算,有需要可以把精度提的更高

  1. dec=Decimal('1.45')在decimal之间进行计算会得到精确的结果,计算后的类型仍然是Decimal类型,print(dec)
  1. Decimal类提供quantize内置函数,它可以按照精度和舍入方式精确的调整数值result=dec.quantize(Decimal('0.01'),rounding=ROUND_UP)print(result)
  1. 若要使用精度不受限的方式表达有理数,那么可以考虑使用Fraction类,包含在内置的fractions模块里

7,学会使用pypi,Python中央仓库:https://pypi.python.org

  1. 如果碰到不熟悉的编程难题,应该去PyPI里看看别人的代码
  1. pip3安装python3版本的软件包,pip安装python2版本的软件包

Effective python(五):内置模块的更多相关文章

  1. 《Effective Python:编写高质量Python代码的59个有效方法》读书笔记(完结)

    Effective Python 第1章 用Pythonic方式来思考 be pythonic 遵守pep8 python3有两种字符序列类型:bytes(原始的字节)和str(Unicode字符). ...

  2. Effective Python之编写高质量Python代码的59个有效方法

                                                         这个周末断断续续的阅读完了<Effective Python之编写高质量Python代码 ...

  3. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  4. 【Python五篇慢慢弹】数据结构看python

    数据结构看python 作者:白宁超 2016年10月9日14:04:47 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...

  5. 【Python五篇慢慢弹(3)】函数修行知python

    函数修行知python 作者:白宁超 2016年10月9日21:51:52 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...

  6. 【Python五篇慢慢弹(4)】模块异常谈python

    模块异常谈python 作者:白宁超 2016年10月10日12:08:31 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondo ...

  7. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

  8. Effective Python 中文版

    如题,博主正在翻译一本Python相关的书. 图为Python作者. [美]Brett Slatkin的名作. Effective Python: 59 Specific Ways to Write ...

  9. Python常用内置模块之xml模块

    xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.从结构上,很像HTML超文本标记语言.但他们被设计的目的是不同的,超文本标记语言被设计用来显示 ...

  10. [Effective Python] 用Pythonic方式来思考

    Effective Python chap.1 用Pythonic方式来思考 Pythonic: 一门语言的编程习惯是由用户来确立的. 1. 确认自己所使用的Python版本 2. 遵循PEP8风格指 ...

随机推荐

  1. 使用Xshell进行vi编辑时,按下end、home和Delete不能使用,解决解决办法

    使用Xshell连接到Linux进行vi编辑时,进入编辑模式,按下end键,光标无法移到行位,home也不能到行首,其它的Delete键也是不能使用,如何解决? Xshell选项设置如下: 文件→属性 ...

  2. 从赴美IPO绝迹 看那些烧成泡沫的互联网企业

    曾经,赴美上市是很多中国企业的终极梦想.然而在当下,随着中概股在美国股市股价的不断走低.中国赴美上市企业私有化速度的加快,大众才发现,原来美国股市并不是那么好混的.但不管怎样,赴美上市始终是一种荣耀. ...

  3. 使用TensorFlow训练自己的语音识别AI

    这次来训练一个基于CNN的语音识别模型.训练完成后,我们将尝试将此模型用于Hotword detection. 人类是怎样听懂一句话的呢?以汉语为例,当听到"wo shi"的录音时 ...

  4. JavaScript学习总结之数组常用的方法和属性

    先点赞后关注,防止会迷路寄语:没有一个冬天不会过去,没有一个春天不会到来. 前言数组常用的属性和方法常用属性返回数组的大小常用方法栈方法队列方法重排序方法操作方法转换方法迭代方法归并方法总结结尾 前言 ...

  5. 完全依赖QML实现播放器

    前言 一直听闻QML无比强大好用,工作中需要扣一个同时播放视频的Demo,所以就趁这个机会研究了一下. 效果图和源码 源码仓库 主要设计 主页面QML import QtQuick 2.12 impo ...

  6. LeetCode python实现题解(持续更新)

    目录 LeetCode Python实现算法简介 0001 两数之和 0002 两数相加 0003 无重复字符的最长子串 0004 寻找两个有序数组的中位数 0005 最长回文子串 0006 Z字型变 ...

  7. Asp.Net Core EndPoint 终点路由工作原理解读

    一.背景 在本打算写一篇关于Identityserver4 的文章时候,确发现自己对EndPoint -终结点路由还不是很了解,故暂时先放弃了IdentityServer4 的研究和编写:所以才产生了 ...

  8. PHP压缩文件夹 php

    $path = PUBLIC_DIR.'/images/'; //待压缩文件夹父目录 $zipPath = PUBLIC_DIR.'/images_zip/'; //压缩文件保存目录 !is_dir( ...

  9. 7-5 jmu-python-分段函数1 (10 分)

    本题目要求计算下列分段函数f(x)的值(x为从键盘输入的一个任意实数): 输入格式: 直接输入一个实数给 x,没有其他任何附加字符. 输出格式: 在一行中按“f(x)=result”的格式输出,其中x ...

  10. sql03

    1.约束 约束详解 ->约束的目的:保证数据的完整性. not null ->默认值约束.可空约束.主键约束.外键约束.唯一键约束.检查约束 1) 用sql语句为表添加新的字段 2) 为字 ...