Python 编程规范指南详解 上

Python 编程规范指南详解 上_第1张图片

Python 编程规范详解指南 上

文章目录

  • Python 编程规范详解指南 上
    • 一、Python 主流编程规范参考指南
      • (一)、PEP 8 风格指南
      • (二)、Google 开源项目风格指南
    • 二、与空白和换行有关的建议
    • 三、与命名有关的建议
    • 四、与表达式和语句有关的建议
    • 五、与引入有关的建议
    • Python 中关于编程规范的小彩蛋
    • 参考资料
    • 文件下载
    • 相关博客


一、Python 主流编程规范参考指南

在讲解 Python 的编程规范之前,我认为有必要让大家了解一下目前主流的编程规范有哪些
目前对于Python主流的编程规范指南,有大名鼎鼎的 PEP 8 指南 以及 Google 开源项目风格指南

编程规范真的是很重要,特别对于正在从事程序员或即将从事程序员的人来说。我们并不是只是一个人在敲代码,如果你的代码风格和其他的程序员的相同,那么就能够更加顺利地与大家一起做项目,这套代码风格理应是编程规范,采用一致的风格可以使代码更易读、更易懂。
如果编程规范不佳,那会极大影响到其他人阅读这份代码的效率,评价一个程序员的能力往往是从代码这第一印象开始的,这就与写字一样,好的程序员肯定是会注重代码规范的
即便代码只是给自己去看,也应该按照编程规范风格来写,以便日后修改时容易阅读一些

在下面的内容中,将以PEP 8 风格指南为主,Google 开源项目风格指南为辅并标注进行讲解

(一)、PEP 8 风格指南

PEP 8Python Enhancement Proposal #8 的简写,中文释义Python的增强提议,它是一份针对 Python 代码格式而编订的风格指南,完整指南网址:https://www.python.org/dev/peps/pep-0008/

Python 开发界用 Pythonic 这个词形容具有特定风格的代码,这种风格是大家在使用Python语言及合作的过程中约定俗成的一种习惯,Python的开发者不喜欢写复杂的代码,会使用直观、简洁且容易看懂的方式去编写程序

(二)、Google 开源项目风格指南

说到谷歌,不会没有人不知道吧,大名鼎鼎的安卓系统就是谷歌公司研发的,中文版的 《Google 开源项目风格指南》 现有五份风格指南,分别是:

  • 《Google C++ 风格指南》
  • 《Google Objective-C 风格指南》
  • 《Google Python 风格指南》
  • 《Google JavaScript 风格指南》
  • 《Google Shell 风格指南》
  • 《Google JSON 风格指南》

这此指南中有这么一段:
每个较大的开源项目都有自己的风格指南,关于如何为该项目编写代码的一系列约定 (有时候会比较武断).。当所有代码均保持一致的风格, 在理解大型代码库时更为轻松。


二、与空白和换行有关的建议

在Python中, 空白(whitespace)在语法上相对重要。空白会影响代码的清晰程度,遵守有关于空白的建议有助于提高阅读效率。

  • 用空格(space)表示缩减,而不要用制表符(tab)『一个tab相当于八个空格』
  • 和语法相关的每一层缩进都使用4个空格表示
  • 每行不超过79个字符,每行不超过80个字符(Google)
  • 对于占据多行的长表达式来说,除了首行以外的其余各行都应该在通常的缩进级别之上再加4个空格
  • 在同一份文件中,函数与类之间用两个空行隔开
  • 在同一个类中,方法与方法之间用一个空行隔开
  • 使用字典时,键与冒号之间不加空格,在写同一行的冒号和值之间应该加一个空格
  • 给变量赋值时,赋值符号的左边和右边各加一个空格,并且只加一个空格就好
  • 给变量的类型做注释(annotation)时,不要把变量名和冒号隔开,但在类型信息前应该有个空格
  • 括号的左右两侧不要有空格
    # 正确的
    spam(ham[1], {"eggs": 2}, [])
    
    # 错误的
    spam( ham[ 1 ], { "eggs": 2 }, [ ] )
    
  • 如果一个文本字符串在一行中放不下,可以使用圆括号来实现隐式行连接,如网址(Google)
    string = ("这是一个非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长"
          	  "非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长的字符串")
    

三、与命名有关的建议

PEP 8 建议采用不同的方式给Python代码中的各个部分命名,这样在阅读代码时,就可以根据这些名称看出它们在Python语言中的角色。

  • 函数、变量及属性用小写字母来拼写,各单词之间用下划线相连,列如:lowercase_underscore

  • 受保护的实例属性,用一个下划线开头,列如:_leading_underscore
    单个下划线前缀有一个约定俗成的含义,那就是告诉程序员以单个下划线开头的变量或方法仅供内部使用,对于类中的属性,单个下划线并没有阻止我们“进入”类并访问该变量的值,但前导下划线的确会影响从模块中导入属性

    # 这是module_A.py文件
    
    def external_func():
       return 23
    
    
    def _internal_func():
       return 42
    
    >>> from my_module import *
    >>> external_func()
    23
    >>> _internal_func()
    NameError: "name '_internal_func' is not defined"
    
  • 私有的实例属性,用两个下划线开头,列如:__double_leading_underscore
    Python解释器会重写属性名称,以避免子类中的命名冲突,作为一个类私有的属性,外部无法直接通过 __属性名 形式对该属性进行访问,但并没有真正意义上的限制我们从外部访问该属性,可以理解成只是将其隐藏,以_类名__属性格式拼接即可访问

    class Test:
    def __init__(self):
        self.attr = 1024
        self.__attr_A = "hello"
        self.__attr_B = "world"
    
    def __func(self):
        return self.__attr_B
    
    >>> test = Test()
    >>> test.attr
    1024
    >>> test.__attr_A
    AttributeError: 'Test' object has no attribute '__attr_A'
    >>> test.__func()
    AttributeError: 'Test' object has no attribute '__func'
    >>> test._Test__attr_A
    'hello'
    >>> test._Test__func()
    'world'
    
  • 类(包括异常)命名时,每个单词的首字母均大写,列如:CapitalizedWord

  • 模块级别的常量,所有的字母都大写,各单词之间用下划线相连接,列如:ALL_CAPS

  • 类中的实例方法,应该把第一个参数命名为self,用来表示该对象本身

  • 类方法的第一个参数,应该命名为cls,用来表示这个类本身


四、与表达式和语句有关的建议

The Zen of Python(Python之禅) 中提到:“每件事都应该有简单的做法,而且最好只有一种”。PEP 8 就试着运用这个理念,来规范表达式和语句的写法

  • 采用行内否定,即把否定词直接写在要否定的内容前面,而不要放在整个表达式的前面,列如应该写 if a is not b,而本身if not a is b

  • 不要通过长度判断容器或序列是不是为空的,列如不要通过if len(somelist) == 0判断somelist是否为 []"" 等空值,而是应该采用if somelist语句,因为Python会把非空的值自动判定为True

  • 不要把if语句、for循环、while循环及except复合语句挤在一行。应该把这些语句分成多行来写,这样更加清晰

  • 推荐使用with语句管理文件,显式的关闭文件,节省系统资源和避免代码操作文件后的其他文件操作问题,以及对文件的意外引用(Google)

    with open("hello.txt", "r") as f_r:
    for line in f_r:
        # 循环打印每一行
        print(line)
    
  • 如果表达式一行写不下,可以用括号括起来,而不要用 \ 符号续航
    反斜线有时也仍然合适,列如长with语句时不能使用括号括起来延续,所以反斜杠是可以接受的

    with open('/path/to/some/file/you/want/to/read') as file_1, \
    		open('/path/to/some/file/being/written', 'w') as file_2:
        file_2.write(file_1.read())
    

五、与引入有关的建议

PEP 8 对于怎样在代码中引入并使用模块,给出了下面几条建议

  • 引入每个模块应该独占一行

    # 正确的
    import os
    import sys
    
    # 错误的
    import os, sys
    
  • import语句(含 from x import y)总是应该放在文件开头

  • 引入模块是,总是应该使用绝对名称,而不应该根据当前模块路径来使用相对名称。列如,要引入bar包中的foo模块,应该完整地写出from bar import foo,即便当前的路径为bar包里,也不应该简写为import foo

  • 如果一定要用相对名称来编写 import 语句,那就应该明确地写成:from . import foo

  • 文件中的import语句应该按顺序划分为三个部分:首先引入标准库里的模块,然后引入第三方模块,最后引入自己的模块,属于同一个部分的import语句按字母顺序排列


Python 中关于编程规范的小彩蛋

import this

在导入这一个神秘标准库后,控制台会打印这么一段来自 Tim Peters 的文章

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

将其进行翻译

Beautiful is better than ugly.
# 优美胜于丑陋(Python以编写优美的代码为目标)
Explicit is better than implicit.
# 明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
Simple is better than complex.
# 简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
Complex is better than complicated.
# 复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)

Flat is better than nested.
# 扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
Sparse is better than dense.
# 间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
Readability counts.
# 可读性很重要(优美的代码是可读的)
Special cases aren't special enough to break the rules.
Although practicality beats purity.
# 即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)

Errors should never pass silently.
Unless explicitly silenced.
#不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写except:pass风格的代码)
In the face of ambiguity, refuse the temptation to guess.
# 当存在多种可能,不要尝试去猜测
There should be one-- and preferably only one --obvious way to do it.
# 而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)
Although that way may not be obvious at first unless you're Dutch.
# 虽然这并不容易,因为你不是 Python 之父(这里的Dutch是指Guido)
Now is better than never.
Although never is often better than *right* now.
# 做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
# 如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)
Namespaces are one honking great idea -- let's do more of those!
# 命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)

Python 本身就是一个简洁又极其优美的语言,通过这些如诗一般的文字充分透露出python编程之美,而这些文章就是大名鼎鼎的python之禅(The Zen of Python)


参考资料

  • 书籍:
    • Effective 系列丛书 《Effective Python》
      这算是我最喜欢的 Python 书之一,非常推荐给大家
  • Python PEP8 手册
  • Google 开源项目风格指南(中文版)

由衷感谢


文件下载

  • Python语言规范 — Google 开源项目风格指南.pdf
  • Python风格规范 — Google 开源项目风格指南.pdf

相关博客

  • Python 编程规范详解指南 下
  • Python 字符串格式化最强详解2.0 『如何输出好看的内容』

你可能感兴趣的:(Python,#,Python,规范,技巧类,python,代码规范)