注1:注意仅使用简单类名来重整名字,因此,如果子类使用相同的类名和属性名,你仍然会名字冲突。
注2:名字重整使一些应用稍有不便,例如调试和 __getattr__()。然而名字重整算法有良好的文档,也容易手工执行。
注3:不是每个人都喜欢名字重整。尝试在避免意外的名字冲突需求和高级调用者的可能应用之间平衡。
设计建议 (Programming Recommendations)
- 某种程度上,代码不应该不利于其他 Python 实现 (PyPy, Jython, IronPython,
Pyrex, Psyco, 等等)。
例如,对 a+=b or a=a+b 形式的语句,不要依赖 CPython 对就地 (in-place) 字符串连接的高效实现。那些语句在 Jython 中运行很慢。对库的性能敏感部分,应该改用 ''.join() 语句。这将保证对不同的实现,字符串连接表现为线性时间。
- 与 None 之类的单件比较,应该总是用 'is' or 'is not',绝不要用等号操作符。
同样,当你本意是 "if x is not None" 时,对写成 "if x" 要小心 -- 例如,当测试一个默认为 None 的变量或参数是否被设置为其他值时,这个其他值可能是一种在布尔上下文中为假的类型 (例如容器)!
- 使用基于类的异常。
在新代码中,禁止使用字符串异常 (String exceptions),因为这一语言特征将在Python 2.6 中被移除。
模块和包应该定义它们自己的特定域的异常基类,该异常基类应该是内建异常类的子类。还始终包含一个类的文档字符串。
例如:
class MessageError(Exception):
"""Base class for errors in the email package."""
类命名约定也适用于这里,尽管当异常是错误时,你应该添加 "Error" 后缀到你的异常类。非错误类异常不需要特殊后缀。
- 当 raise 一个异常时,使用 "raise ValueError('message')" 代替旧的 "raise ValueError, 'message'"。
首选采用使用圆括号的形式,因为当异常参数很长或者包括格式化字符串时,你不需要使用行延续符,感谢包含的圆括号。在 Python 3000 中将移除旧的形式。
- 在捕获异常时,尽可能写出明确的异常,而不是使用空的 'except:' 子句。
例如使用:
try:
import platform_specific_module
except ImportError:
platform_specific_module = None
空的 'except:' 子句将捕获 SystemExit and KeyboardInterrupt 异常,这使得用Control-C 中断程序变得困难,也会掩饰其他问题。如果你想捕获全部导致程序错误的异常,就使用 'except StandardError:'。
一个好的经验方法是把空的 'except' 子句限制用在两种情况:
1) 如果异常处理器将打印出或者日志记录 traceback,至少用户将知道有错误发生。
2) 如果代码需要做一些清除工作,但然后用 'raise' 来向上传播异常。对这种情况,'try...finally' 是一种更好的处理方法。
- 另外,对所有 try/except 子句,把 'try' 子句限制在有需要的绝对最少量代码。
这再次避免掩饰 bugs。
- 使用字符串方法代替 string 模块。
字符串方法总是很快,而且和 unicode 字符串共用同样的 API。如果必须向后兼容Python 2.0 以前的版本,可不考虑此规则。
- 使用 ''.startswith() and ''.endswith() 代替字符串切片,来检查前缀和后缀。
startswith() and endswith() 更清晰易读,也倾向于减少错误。例如:
如你的代码必须工作在 Python 1.5.2 (希望不是!),则除外。
- 对象类型的比较应该始终用 isinstance() 代替直接比较类型。
检查一个对象是否是字符串时,紧记它也可能是 unicode 字符串!在 Python 2.3中,str 和 unicode 有公共的基类 basestring,所以你可以这样做:
if isinstance(obj, basestring):
在 Python 2.2 中,types 模块为此定义了 StringTypes 类型,例如:
在 Python 2.0 和 2.1 中,你应该这样做:
- 对序列 (字符串 (strings),列表 (lists),元组 (tuples)),使用空序列为假这个事实。
Yes: if not seq:
if seq:
No: if len(seq)
if not len(seq)
- 不要书写依赖于有意义的后置空白字符的文本字符串。这种后置空白字符在视觉上不可区分,并且有些编辑器 (或者最近,reindent.py) 会将它们裁剪掉。
- 不要用 == 来把布尔值与 True 或 False 进行比较。
References
[1] PEP 7, Style Guide for C Code, van Rossum
[2] http://www.python.org/doc/essays/styleguide.html
[3] PEP 257, Docstring Conventions, Goodger, van Rossum
[4] http://www.wikipedia.com/wiki/CamelCase
[5] Barry's GNU Mailman style guide
http://barry.warsaw.us/software/STYLEGUIDE.txt
[6] PEP 20, The Zen of Python
[7] PEP 328, Imports: Multi-Line and Absolute/Relative
Copyright
This document has been placed in the public domain.