预计所需阅读时间:5分钟

这篇文章是根据Google开源项目风格指南总结而来,原文链接:https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_style_rules/。因为大部分IDE都会有编程语言格式化插件,选择部分或全部代码即可一键格式化,例如Pycharm等。但有时候,这些不一定能对所有规范格式化到位,因为有些地方是多种写法。这里参照Google的定法,根据自己使用Pycharm里不一定能很好格式化的地方,或者见到它代码没有很遵守规范的地方进行的总结。

1、每行要长度在不行超尾过80个字符,但长的导入模块语句和注释的URL例外。通常在做网页开发或爬虫的时候会有长的URL,如果是代码中URL,可以手动回车,Pycharm会在后面加上反斜杠 \,而注释不断行,方便点到此乃的原文。

2、Python会将圆括号,中括号和花括号中的行隐式的连接起来。除非是用于实现行连接,否则不要在返回语句return或条件语句中使用括号。

x = ('This will build a very long long '
     'long long long long long long string')

3、用4个空格来宿进,非专业IDE要加强使用,Pycharm用Tab默认是四个空格。

4、Python有一种独一无二的的注释方式: 使用文档字符串。文档字符串是包、模块、类或函数里的第一个语句。这些字符串可以通过对象的__doc__成员被自动提取, 并且被pydoc所用。我们对文档字符串的惯例是使用三重双引号。在Pycharm的函数下输入三个双引号即会列出要完善的内容。

5、最需要写注释的是代码中那些技巧性的部分。如果你在下次代码审查的时候必须解释一下,那么你应该现在就给它写注释。对于复杂的操作,应该在其操作开始前写上若干行注释。对于不是一目了然的代码,应在其行尾添加注释。

6、如果一个类不继承自其它类,就显式的从object继承,嵌套类也一样。即class SampleClass(object):。继承自object是为了使属性(properties)正常工作。

7、避免在循环中用+和+=操作符来累加字符串。由于字符串是不可变的,这样做会创建不必要的临时对象,并且导致二次方而不是线性的运行时间。作为替代方案,你可以将每个子串加入列表,然后在循环结束后用.join 连接列表。

Yes: items = ['<table>']
     for last_name, first_name in employee_list:
         items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name))
     items.append('</table>')
     employee_table = ''.join(items)

8、在文件和sockets结束时,显式的关闭它。推荐使用with语句。对于不支持with,可以用以下方法来调用。

import contextlib

with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
    for line in front_page:
        print line

9、为临时代码使用TODO注释,它是一种短期解决方案,写上自己的名字、email、截止日期或事件的时间点。

# TODO([email protected]): Use a "*" here for string repetition.
# TODO(Zeke) Change this to use relations.

10、每个导入应该独占一行。导入总应该放在文件顶部,位于模块注释和文档字符串之后,模块全局变量和常量之前。导入应该按照从最通用到最不通用的顺序分组:1.标准库导入、2.第三方库导入、3.应用程序指定导入。

11、即使是一个打算被用作脚本的文件,也应该是可导入的。并且简单的导入不应该导致这个脚本的主功能(main functionality)被执行,这是一种副作用。主功能应该放在一个main()函数中。在Python中,pydoc以及单元测试要求模块必须是可导入的。你的代码应该在执行主程序前总是检查 if __name__ == '__main__',这样当模块被导入时主程序就不会被执行。

def main():
      ...

if __name__ == '__main__':
    main()

12、在Python中,对于琐碎又不太重要的访问函数,你应该直接使用公有变量来取代它们,这样可以避免额外的函数调用开销。当添加更多功能时,你可以用@property来保持语法的一致性。

class Screen:
    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, w):
        self._width = w

另一方面,如果访问更复杂,或者变量的访问开销很显著,那么你应该使用像get_foo()和set_foo()这样的函数调用。如果之前的代码行为允许通过属性@property访问,那么就不要将新的访问函数与属性绑定。这样,任何试图通过老方法访问变量的代码就没法运行,使用者也就会意识到复杂性发生了变化。