受益于《编写高质量代码 改善Python程序的91个建议》,大家有时间可以看下
基础(1-7)
- 理解Pythonic概念
- 编写Pythonic代码
- 理解Python与C语言的不同之处
- 在代码中适当添加注释
- 通过适当添加空行是代码布局更优雅、合理
- 编写函数的4个原则、
- 函数设计要尽量短小,嵌套层次不宜过深
- 函数申明应该做到合理、简单、易于使用
- 函数参数设计应该考虑向下兼容
- 一个函数只做一件事,尽量保证函数语句粒度的一致性
将变量集中到一个文件
编程惯用法(8-18)
- 利用assert(断点)语句来发现问题
- 数据交换值的时候不推荐使用中间变量
- 充分利用Lazy evaluatin(延迟计算)的特性>生成器
- 避免不必要的计算,带来性能上的提升
- 节省空间,是的无限循环的数据结构成为可能
- 理解枚举替代实现的缺陷
- 使用类属性
- 借助函数
- 使用collections.namedtuple
不推荐使用type来进行类型检查
:基于内建类型扩展的用户自定义类型,type并不能准确返回结果- 尽量转换为浮点类型后再做除法
- 警惕eval()的安全漏洞
- 如果对象不是信任源,应该尽量避免使用eval
- 在需要使用eval的地方可用安全性更好的ast.literal_eval替代
- 使用enumerate()获取序列迭代的索引和值
li = [1, 2, 3, 4]
for i, e in enumerate(li):
print("index": i)
print("element": e)
分清 == 和 is 的使用场景
- ==:检查两个对象的值是否相等
- is:检查对象的标识符是否一致,比较两个对象在内存中是否拥有同一块内存
考虑兼容性,尽可能使用Unicode
!!!- 构建合理的包层次来管理module
- 合理组织代码,便于维护和使用
- 能够有效的避免名称空间冲突
基础语法(19-35)
- `有节制的使用from…import…语句
- 一般情况下尽量优先使用import A(A.b)
- 有节制的使用form A import b (直接访问b)
- 尽量避免from A import * (污染命名空间)
- 优先使用absolute imort来导入模块
i += 1不等于++i
- 使用with自动关闭资源
- 使用else子句简化循环(异常处理)
- 遵循异常处理的几点基本原则
- 注意异常的粒度,不推荐在try中放入过多的代码
- 谨慎使用单独的except语句来处理所有异常
- 注意异常捕获的顺序,在合适的层次处理异常
- 使用更为友好的异常信息,遵循异常参数的规范
- 避免finally中可能发生的陷阱,不推荐在finally中return返回
- 深入理解None,正确判断对象是否为空
连接字符串应优先使用join而不是+
格式化字符串时尽量使用.format方式而不是%
- 区别对待可变对象和不可变对象
()、[]、{}
:一致的容器初始化形式记住函数传参既不是传值也不是传引用
- 警惕默认参数潜在的问题
- 慎用变长参数
- *args来实现可变参数列表
- **kwargs接受字典形式的关键字参数列表
- 装饰器
- 参数的数目不确定
- 实现函数的多态或者继承情况下子类需要调用父类的某些方法
- 深入了解str()和repr()的区别
- 两者目标不同
- str():主要面向用户,目的是可读性
- repr():面向Python解释器,目的是准确性
- 在解释器中直接输入a时默认调用repr(),而print(a)调用str()
- repr()的返回值一般可以用eval()函数还原
- 分别调用內建的__str()和__repr(),一般类中都有__repr()__,而__str()__为可选
- 两者目标不同
- 分清staticmethod(静态方法)和classmethod(类方法)的适用场景
class A(object):
@staticmethod
def a(arg1):
pass
class B(object):
@classmethod
def b(arg2):
pass
库(36-49)
- 掌握字符串的基本用法
- 按需选择sort()或者sorted()
- 相对于sort(),sorted()适用范围更广
- 当排序对象为列表时,适用不同
- 两者传入参数key比传入参数cmp效率更高
- sorted()函数功能非常强大,可以方便的针对不同的数据结构进行排序
- 对字典进行排序
- 多维list排序
- 字典中混合list排序
- list中混合字典排序
- 使用copy模块深拷贝对象
- 深拷贝:构造一个新的复合对象,并将原对象中发现的引用插入该对象中
- 浅拷贝:构造一个新的复合对象,遇到引用会继续递归拷贝其所指向的具体内容
- 使用Counter进行计数统计
- 深入掌握ConfigParser
- 使用argparse处理命令行参数
使用pandas处理大型csv文件
一般情况使用ElementTree解析XML
- 理解模块pickle优劣
- 序列化的另一个不错的选择–JSON
- 使用traceback获取栈信息
- 使用logging记录日志信息
使用threading木块编写多线程程序
49使用Queue使多线程编程更安全
设计模式(50-53)
- 利用模块实现单例模式
- 用mini模式让程序更灵活
用发布订阅模式实现松耦合
- 用状态模式美化代码
内部机制(54-69)
- 理解built-in objects
__init__()不是构造方法
- 理解名字查找机制
- 局部作用域
- 全局作用域
- 嵌套作用域
- 内置作用域
为什么需要self参数
- 理解MRO与多继承
- 理解描述符机制
- 区别__getattr__()和__getattrbute__()方法
使用更为安全的property
- 代码更简洁,可读性更高
- 更好的管理属性的访问
- 代码可维护性更好
- 控制属性访问权限
- 掌握metaclass(元类)
- 熟悉Python对象协议
- 利用操作符重载视线中缀语法
- 熟悉Python迭代器协议
- 实现__iter__()方法,返回一个迭代器
- 实现next()方法,返回当前元素,并指向下一个元素位置,如果当前已无元素,则抛出StopIteration异常
- 熟悉Python生成器
- 基于生成器的协程及greenlet
- 理解GIL的局限性
- 对象的管理与垃圾回收
实用工具辅助项目开发(70-78)
- 从PyPI安装包
- 使用pip和yolk安装、管理包
- 做paster创建包
- 理解单元测试概念
- 为包编写单元测试
- 利用测试驱动开发提高代码的可测性
- 使用Pylint检查代码风格
- 进行高效的代码审查
- 将包发布到PyPI
性能剖析与优化(79-91)
- 了解代码优化的基本原则
- 优先保证代码是可工作的
- 权衡优化的代价
- 定义性能指标,集中力量解决首要问题
- 不要忽略可读性
- 借助性能优化工具
- 利用cProfile定位性能瓶颈
- 使用memory_profiler和objgraph剖析内存使用
- 努力降低算法复杂度
- 掌握循环优化的基本技巧
- 使用生成器提高效率
- 使用不同的数据结构优化性能
- 充分利用set的优势
- 对list求相同的元素,set求并集
- 向list和set中添加元素,当元素规模为100时,list耗时set的9倍
- 使用multiprocessing客服GIL的缺陷
- 使用线程池提高效率
- 使用C/C++模块扩展高性能
- 使用Cython编写扩展模块
评论区