be pythonicpython
遵照pep8算法
python3有两种字符序列类型:bytes(原始的字节)和str(Unicode字符).安全
数据结构
应该尽量使用if/else表达式和辅助函数来使代码清晰多线程
不要在单次切片中同时指定start, end和stride.能够采用两步进行范围切割和步进切割.闭包
使用列表推导来代替map和filter并发
不要在列表推导中使用两个以上的表达式.使用if和for语句代替.ide
若是数据量很大,用生成器表达式来改写列表推导.生成器表达式会返回一个迭代器,而后能够用next来生成新值.函数
若是须要同时使用list的索引和元素,最好使用enumerate替代range性能
用zip函数同时遍历2个迭代器
利用try/except/else/finally进行异常处理
尽可能用异常来表示特殊状况,而不是None
python支持闭包,闭包是一种定义在某个做用域的函数,这种函数引用了那个做用域里的变量.
python的函数是一级对象,也就是能够直接引用,能够赋给变量,能够当成参数传给其余函数.
函数中的局部变量不会影响外部做用域.若是须要获取闭包函数内的数据,应该使用nonlocal声明变量.若是使用nonlocal让代码变得复杂,应该将相关的函数封装成辅助类.
若是函数返回列表,能够考虑用生成器改写,将return变为yield.
若是须要在函数中屡次迭代一个生成器,能够考虑把写一个容器,把__iter__方法实现为生成器.
令函数接受可选的位置参数*args,可以使代码清晰.若是要把列表中的全部元素做为位置参数传入,就在列表前加上*.
可选参数有两个问题,一个是过长的生成器做为参数会致使消耗大量内存,一个是不方便修改函数.
能够用关键字参数表示函数可选的行为和默认值.参数的默认值会在模块加载的时候求出.所以不要在参数默认值中建立[]或{}等动态的值.解决方法是把默认值设为None,并在docstring中具体解释.
能够在定义函数的时候用*来分隔位置参数和关键字参数(只能以关键字指定的参数)
当数据结构比较复杂时,尽可能用辅助类来维护程序的状态,而不要用字典和元组.
相似sort的key参数能够接受一个函数,这称挂钩(hook)函数.
简单的接口应该接受函数而不是类的实例,由于函数是一级对象.
若是要用函数保存状态,应该定义新的类并实现__call__方法
经过@classmethod能够构造多态的类的对象.
较复杂的继承体系中,若是仍让子类直接调用父类的__init__,会出现不少意想不到的行为,所以建议用super初始化父类.
mix-iin是一种只定义了其余类可能须要提供的一套附加方法的小型类.只在使用mix-in组件类时进行多重继承.
Python类的属性只有public和private.通常还会用单个下划线开头来习惯性命名protected.
private属性是开头至少有两个下划线,结尾至多有一个下划线的属性.python对于__private_name的保存机制其实是_ClassName__private_name.所以能够经过这种方式访问全部private属性.
应该多用前者,少用后者.
若是要定制简单子类,能够直接从python的容器类型继承.不然能够继承collections.abc中的抽象基类以实现自定义的容器类型.
用纯属性取代get和set方法
若是想要使用get和set,应该使用@property修饰器的getter和setter.它的缺点是不便于复用.
描述符能够把同一套逻辑运用在类中的不一样属性上面.
WeakKeyDictionary能够保证描述符类不会泄露内存
并发(concurrency)是指计算机经过迅速切换看似在同一时间作不少不一样的事.并行(parallelism)则是指计算机确实在同一时间作不少不一样的事.
subprocess用于与外部进程交互.
Python解释器能平行地运行多条子进程.
GIL确保了字节码解释器的协调性,但也带来了同一时刻只能进行一条线程的负面影响.所以Python的多线程适用于处理阻塞式的I/O操做,而不是平行计算.
Python多线程一样须要使用Lock来防止数据竞争,由于解释器可能会在线程的任意时刻暂停它们.
用queue.QUeue来协调各线程之间的工做.它解决了并发式管道存在的问题.
线程存在的问题是:代码复杂,须要占用大量内存(大约8mb),启动时的开销比较大.协程能够避免这些问题.
协程的工做原理是:每当生成器函数执行到yield表达式时,消耗生成器的那段代码,就经过send方法给生成器回传一个值.
concurrent.futures会以子进程的形式平行地运行多个解释器,从而令python可以利用多核心CPU来提高速度.这种作法适用于较为孤立且数据利用率高的任务.
functools.wraps能够定义函数修饰器,用于在函数执行以前以及执行完毕以后分别运行一些附加代码.能够实现约束语义,调试程序,注册函数等目标.
contextlib模块可使本身编写的对象和函数支持with语句.
python的pickle模块能将python对象序列化为字节流,也能将这些字节反序列化为python对象.可是这种序列化数据采用的是不安全的格式,若是其中有恶意信息,在反序列化时可能对程序形成损害.Json数据则是安全的.
copyreg能使pickle变得可靠.
使用datetime而不是time来处理本地时间
使用内置的算法和数据结构,例如collections.deque双向队列,collections.OrderedDict有序字典,collections.defaultdict带有默认值的字典,heapq堆,bisect二分查找,itertools处理迭代器.
在重视精确度的场合,应该使用decimal
为每一个函数,类和模块编写docstring.
用包来安排模块,并提供稳固的API.
为自编的模块定义根异常,以便将调用者与API相隔离.
能够用模块级别的代码来配置不一样的部署环境
经过repr来输出调试信息
用unittest来测试代码
pdb模块的set_trace()可让程序在执行到某一行的时候暂停,用于调试.
利用cProfile来分析每一个模块的性能,而后再优化.
用tarcemalloc来掌握内存的使用及泄露状况.