Python代码风格建议(转)

python 以其结构严格著称,同时也以其命名规范散漫出名,算乱无规矩的命名尤其给开发人员带来理解上的误区。

尤其像python、ruby动态语言,由于在运行期随时可能出现方法或者属性的增减,规则的命名尤其重要。

ruby语言本身定义的语法规则较为随意,但却不乏一一对应的隐含规则,使人一目了然。其命名规则甚至渗透进了语言本身的规范当中

在命名规则这一点上python显得没规没距。需要逐步养成一个好的编码命名规范。

本文从各大站点文章中搜集了一些代码风格,命名规范。便于学习参考。

代码风格:

  1. 使用空格来表示缩进,而不要使用制表符tab,请勿将两者混用
  2. 函数间换行至少一行
  3. 类之间换行至少两行
  4. dict、list、tuple、参数列表时,应该在逗号,前添加一个空格
  5. dict中key之后的冒号:应在value与冒号:之间添加空格,而不是:与key之前间
  6. 较长代码(大于79chars)使用反斜杠\换行。换行后新行的起始处应该与前一个分隔符对齐(是参数换行则与左括号(对齐
  7. import位于module comments 与 docstring 之后,常量声明之前
  8. 3.0一下版本的代码文件建议以latin字符编码。3.0以上则推荐utf-8
  9. 代码中有操作符运算,请注意优先级,优先的操作紧缩,或者加括号
  10. 等号左右两边请勿加空格
  11. 尽量不要将多行代码放在同一行
  12. 少使用inline comments(行后注释)
  13. block comments (用#开头的多行函数注释),保持与目标函数 相同的缩进
  14. docstring ,开头一行写上返回值,接下来一行写函数功能描述,后可按照格式>>>func(arg1, arg2, arg3) /r 返回值。以便于测试
  15. 另外,若要使用subversion,cvs等源代码管理工具。可以在函数的docstring 之后,code之前 写上
    1. __version__ = "Revision:16dd63848921"

命名规则:

  1. 尽量少用 ‘l‘ (lowercase letter el), ‘O‘ (uppercase letter oh), or ‘I‘ (uppercase letter eye) 单字母作为变量的命名.-------no l,I,O
  2. 包和模块应该用短且全小写字母(Modules should have short, all-lowercase names.):thismoduleisnew
  3. class name 则建议用CapWords(首字母大写)的形式命名:NewClassName
  4. Exception类则用以Error结尾的字符串命名为宜: NewError
  5. 全局变量尽量只是设计用于模块内使用,并且可以用import *时,包内的__all__机制来除去全局变量
  6. 函数名(function name) 尽量都用小写且单词间以_(下划线)连接,另外,大小混合的mixedCase植被允许用于传统类中。function_name(arg1...)
  7. 函数和方法参数(function and method arguments),self作为实例方法的第一个参数,cls作为类方法的第一个参数,倘若参数名与关键字相同,为了避讳,则应该加个下划线
  8. 方法名&类实例的属性(method name & instance variable)方法名规则与函数名相同,类实例私有属性 和 类实例的私有方法以单个下划线开头_private_fucntion_name(self)
  9. 常量;全大写,单词间以_下弧线间隔:THIS_IS_CONSTANT_VAR
  10. 面向对象设计建议:
    1. 若对类实例中的属性是设置成public的好还是private好,可以考虑先设置成private,其修改成本更低。
    2. private不能被第三方使用,因为随时有可能被删除、废弃
    3. public属性不能用下划线开头
    4. 避免属性使用大运算量操作
    5. 倘若不想被子类继承的属性,应该用双下划线开头,且最后没有下划线。这样会启动python的命名识别矫正处理算法,保证不被继承
  1. joined_lower 可以是函数名 方法名 属性名
  2. ALL_CAPS 是常量
  3. StudlyCaps是类名
  4. camelCase 只有在预先订制好的命名规范中使用
  5. 属性 interface,_internal, __private
  6. 尽量避免__private形式,下面两个连接解释了为什么python中没有private声明

最后没时间翻译了,有时间再来。

Reference: http://www.python.org/dev/peps/pep-0008/#naming-conventions

Programming Recommendations

  • Code should be written in a way that does not disadvantage other implementations of Python (PyPy, Jython, IronPython, Cython, Psyco, and such).

    For example, do not rely on CPython‘s efficient implementation of in-place string concatenation for statements in the form a += b or a = a + b. Those statements run more slowly in Jython. In performance sensitive parts of the library, the ‘‘.join() form should be used instead. This will ensure that concatenation occurs in linear time across various implementations.

  • Comparisons to singletons like None should always be done with is or is not, never the equality operators.

    Also, beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

  • When implementing ordering operations with rich comparisons, it is best to implement all six operations (__eq____ne____lt____le____gt____ge__) rather than relying on other code to only exercise a particular comparison.

    To minimize the effort involved, the functools.total_ordering() decorator provides a tool to generate missing comparison methods.

    PEP 207 indicates that reflexivity rules are assumed by Python. Thus, the interpreter may swap y > x with x < yy >= x with x <= y, and may swap the arguments of x == y and x != y. The sort() and min() operations are guaranteed to use the < operator and the max() function uses the > operator. However, it is best to implement all six operations so that confusion doesn‘t arise in other contexts.

  • Use class-based exceptions.

    String exceptions in new code are forbidden, because this language feature is being removed in Python 2.6.

    Modules or packages should define their own domain-specific base exception class, which should be subclassed from the built-in Exception class. Always include a class docstring. E.g.:

    class MessageError(Exception):
        """Base class for errors in the email package."""
    

    Class naming conventions apply here, although you should add the suffix "Error" to your exception classes, if the exception is an error. Non-error exceptions need no special suffix.

  • When raising an exception, use raise ValueError(‘message‘) instead of the older form raise ValueError, ‘message‘.

    The paren-using form is preferred because when the exception arguments are long or include string formatting, you don‘t need to use line continuation characters thanks to the containing parentheses. The older form will be removed in Python 3.

  • When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause.

    For example, use:

    try:
        import platform_specific_module
    except ImportError:
        platform_specific_module = None
    

    A bare except: clause will catch SystemExit and KeyboardInterrupt exceptions, making it harder to interrupt a program with Control-C, and can disguise other problems. If you want to catch all exceptions that signal program errors, use except Exception: (bare except is equivalent to except BaseException:).

    A good rule of thumb is to limit use of bare ‘except‘ clauses to two cases:

    1. If the exception handler will be printing out or logging the traceback; at least the user will be aware that an error has occurred.
    2. If the code needs to do some cleanup work, but then lets the exception propagate upwards with raisetry...finally can be a better way to handle this case.
  • Additionally, for all try/except clauses, limit the try clause to the absolute minimum amount of code necessary. Again, this avoids masking bugs.

    Yes:

    try:
        value = collection[key]
    except KeyError:
        return key_not_found(key)
    else:
        return handle_value(value)
    

    No:

    try:
        # Too broad!
        return handle_value(collection[key])
    except KeyError:
        # Will also catch KeyError raised by handle_value()
        return key_not_found(key)
    
  • Context managers should be invoked through separate functions or methods whenever they do something other than acquire and release resources. For example:

    Yes:

    with conn.begin_transaction():
        do_stuff_in_transaction(conn)
    

    No:

    with conn:
        do_stuff_in_transaction(conn)
    

    The latter example doesn‘t provide any information to indicate that the __enter__ and __exit__ methods are doing something other than closing the connection after a transaction. Being explicit is important in this case.

  • Use string methods instead of the string module.

    String methods are always much faster and share the same API with unicode strings. Override this rule if backward compatibility with Pythons older than 2.0 is required.

  • Use ‘‘.startswith() and ‘‘.endswith() instead of string slicing to check for prefixes or suffixes.

    startswith() and endswith() are cleaner and less error prone. For example:

    Yes: if foo.startswith(‘bar‘):
    No:  if foo[:3] == ‘bar‘:
    

    The exception is if your code must work with Python 1.5.2 (but let‘s hope not!).

  • Object type comparisons should always use isinstance() instead of comparing types directly.
    Yes: if isinstance(obj, int):
    
    No:  if type(obj) is type(1):
    

    When checking if an object is a string, keep in mind that it might be a unicode string too! In Python 2.3, str and unicode have a common base class, basestring, so you can do:

    if isinstance(obj, basestring):
    
  • For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
    Yes: if not seq:
         if seq:
    
    No: if len(seq)
        if not len(seq)
    
  • Don‘t write string literals that rely on significant trailing whitespace. Such trailing whitespace is visually indistinguishable and some editors (or more recently, reindent.py) will trim them.
  • Don‘t compare boolean values to True or False using ==.
    Yes:   if greeting:
    No:    if greeting == True:
    Worse: if greeting is True:
    
  • The Python standard library will not use function annotations as that would result in a premature commitment to a particular annotation style. Instead, the annotations are left for users to discover and experiment with useful annotation styles.

    Early core developer attempts to use function annotations revealed inconsistent, ad-hoc annotation styles. For example:

    • [str] was ambiguous as to whether it represented a list of strings or a value that could be either str or None.
    • The notation open(file:(str,bytes)) was used for a value that could be either bytes or str rather than a 2-tuple containing a str value followed by abytes value.
    • The annotation seek(whence:int) exhibited an mix of over-specification and under-specification: int is too restrictive (anything with __index__ would be allowed) and it is not restrictive enough (only the values 0, 1, and 2 are allowed). Likewise, the annotation write(b: bytes) was also too restrictive (anything supporting the buffer protocol would be allowed).
    • Annotations such as read1(n: int=None) were self-contradictory since None is not an int. Annotations such as source_path(self, fullname:str) -> objectwere confusing about what the return type should be.
    • In addition to the above, annotations were inconsistent in the use of concrete types versus abstract types: int versus Integral and set/frozenset versus MutableSet/Set.
    • Some annotations in the abstract base classes were incorrect specifications. For example, set-to-set operations require other to be another instance of Set rather than just an Iterable.
    • A further issue was that annotations become part of the specification but weren‘t being tested.
    • In most cases, the docstrings already included the type specifications and did so with greater clarity than the function annotations. In the remaining cases, the docstrings were improved once the annotations were removed.
    • The observed function annotations were too ad-hoc and inconsistent to work with a coherent system of automatic type checking or argument validation. Leaving these annotations in the code would have made it more difficult to make changes later so that automated utilities could be supported.
时间: 2024-11-12 08:58:09

Python代码风格建议(转)的相关文章

如何使用 Pylint 来规范 Python 代码风格

https://www.ibm.com/developerworks/cn/linux/l-cn-pylint/ Pylint 是什么 Pylint 是一个 Python 代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准(Pylint 默认使用的代码风格是 PEP 8,具体信息,请参阅参考资料)和有潜在问题的代码.目前 Pylint 的最新版本是 pylint-0.18.1. Pylint 是一个 Python 工具,除了平常代码分析工具的作用之外,它提供了更多的功能:如

python代码风格指南:pep8 中文翻译

摘要 本文给出主Python版本标准库的编码约定.CPython的C代码风格参见?PEP7.本文和?PEP 257 文档字符串标准改编自Guido最初的<Python Style Guide>, 并增加了Barry的?GNU Mailman Coding Style Guide的部分内容.本文会随着语言改变等而改变.许多项目都有自己的编码风格指南,冲突时自己的指南为准. 本文给出主Python版本标准库的编码约定.CPython的C代码风格参见PEP7. 本文和PEP 257 文档字符串标准改

python代码风格指南:pep8 中文版

本文档所提供的编码规范,适用于主要的Python发行版中组成标准库的Python代码.请参阅PEP关于Python的C实现的C编码风格指南的描述. 本文档和PEP257(文档字符串规范)改编自Guido的<Python Style Guide>一文,并从<Barry's style guide>添加了部分内容作为补充. 这篇风格指南随着时间的推移而逐渐演变,随着语言本身的变化,一些过去的约定已经过时,并确定了更多新的约定. 许多项目都有自己的编码风格指南.如果有任何冲突,优先使用该

代码风格建议

1.代码风格一致,注意折行.缩进.空行.注释 2.对变量.宏..枚举等进行注释 3.缩进最好不用tab,而是使用4个空格 4.单行注释最好不要与代码同行 5.对错误进行全局管理 6.引进需要的命名空间 7.使用预编译头文件,将自己写的头文件与系统头文件分开 8.有完整规范的日志输出,日志要有层次性 9.有些if判断后的返回可以用断言代替(断言:assert(expr),不满足条件即终止运行)

这7大神器, 让你的Python 代码更易于维护

当软件项目进 入"维护模式"时,对代码的可读性和编码标准经常就忽略了(甚至从一开始就没有建立起这些标准.)但是,在代码库中保持一致的风格和测试标准是减少维护负担的重要因素,它能确保未来的开发人员能够快速了解新的项目情况 - 并保持项目的良好运行 保护项目未来可维护性的一个好方法就是使用外部库来检查你的代码运行状况.以下是我们最喜欢的一些用于检查代码的库(包含检查PEP 8和其他样式错误),让代码风格保持一致,并确保在项目成熟时的测试覆盖率保持在可接受范围. 检查你的代码风格 PEP 8

使用Pylint规范你的Python代码

Pylint是一个Python代码风格的检查工具,功能上类似于pychecker,默认用PEP8作为代码风格标准,它所提供的功能包括:检查代码行的长度,检查变量命名是否符合规范,检查声明的接口是否被真正的实现等等,详细信息参考:http://docs.pylint.org/. 安装: sudo apt-get install pylint ? #Ubuntu pip install pyint ? #windows 更多安装方式可以查看:http://www.pylint.org/#instal

python代码检查工具pylint 让你的python更规范

1.pylint是什么? Pylint 是一个 Python 代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准(Pylint 默认使用的代码风格是 PEP 8,具体信息,请参阅参考资料)和有潜在问题的代码.目前 Pylint 的最新版本是 pylint-0.18.1. Pylint 是一个 Python 工具,除了平常代码分析工具的作用之外,它提供了更多的功能:如检查一行代码的长度,变量名是否符合命名标准,一个声明过的接口是否被真正实现等等. Pylint 的一个很大的好

转:python代码缩进

习惯了java,c++之类的宽容,初学python,被它摆了道下马威,写if else,竟然必须要我正确用缩进格式,原来在python里不能用括号来表示语句块,也不能用开始/结束标志符来表示,而是靠缩进来表示,好吧,我以后多注意 空白在Python中是重要的.事实上行首的空白是重要的.它称为缩进.在逻辑行首的空白(空格和制表符)用来决定逻辑行的缩进层次,从而用来决定语句的分组.这意味着同一层次的语句必须有相同的缩进.每一组这样的语句称为一个块.我们将在后面的章节中看到有关块的用处的例子. 你需要

编写高质量Python代码的59个有效方法

作者Brett Slatkin是 Google公司高级软件工程师.他是Google消费者调查项目的工程主管及联合创始人,曾从事Google App Engine的Python基础架构工作,并利用Python来管理众多的Google服务器.Slatkin也是PubSubHubbub协议的联合创始人,还用Python为Google实现了针对该协议的系统.他拥有哥伦比亚大学计算机工程专业学士学位. 精彩书评 "Slatkin所写的这本书,其每个条目(item)都是一项独立的教程,并包含它自己的源代码.