Python基础编码规范

一、代码布局

缩进

        建议采用空格最为缩进方式,程序中每一级缩进使用4个空格,首行无空格。

def function():
    pass 

行的最大长度

        建议所有行限制的最大字符数为79。超出长度的换行继续.

在二元运算符之前应该换行吗?

        尽量不换行

空行

        顶层函数和类的定义,前后用两个空行隔开。 

        类里的方法定义用一个空行隔开。 

        相关的功能组可以用额外的空行(谨慎使用)隔开。一堆相关的单行代码之间的空白行可以省略(例如,一组虚拟实现 dummy implementations)。 

        在函数中使用空行来区分逻辑段(谨慎使用)。 

        Python接受control-L(即^L)换页符作为空格;许多工具把这些字符当作页面分隔符,所以你可以在文件中使用它们来分隔相关段落。请注意,一些编辑器和基于Web的代码阅读器可能无法识别control-L为换页,将在其位置显示另一个字形。

源文件编码

        Python核心发布版本中的代码均是以UTF-8格式编码

Import 导入

# 推荐: 
import os
import sys

# 不推荐:  
import sys, os

# 推荐:
from subprocess import Popen, PIPE

字符串引号

        在Python中,单引号和双引号字符串是相同的。

 

二、表达式和语句中的空格

紧跟在小括号,中括号或者大括号后

# 推荐: 
spam(ham[1], {eggs: 2})

# 不推荐:  
spam( ham[ 1 ], { eggs: 2 } )

紧贴在逗号、分号或者冒号之前。      

# 推荐: 
if x == 4: print x, y; x, y = y, x

# 不推荐:  
if x == 4 : print x , y ; x , y = y , x

紧贴在函数参数的左括号之前。

# 推荐:  
spam(1)

# 不推荐:  
spam (1)

三、注释

        与代码相矛盾的注释比没有注释还糟,当代码更改时,优先更新对应的注释! 

        注释应该是完整的句子。如果一个注释是一个短语或句子,它的第一个单词应该大写,除非它是以小写字母开头的标识符

        注意:永远不要改变标识符的大小写!。 

        如果注释很短,结尾的句号可以省略。块注释一般由完整句子的一个或多个段落组成,并且每句话结束有个句号。 

        在句尾结束的时候应该使用两个空格。 

.py文件头注释

        头注释是用来标明文件编码及作者等等一些基本信息的注释信息

        推荐使用模板:

 

单行注释-块注释

        块注释通常适用于跟随它们的某些(或全部)代码,并缩进到与代码相同的级别。块注释的每一行开头使用一个#和一个空格(除非块注释内部缩进文本)。 

        块注释内部的段落通过只有一个#的空行分隔。

        例:

 

单行注释-行内注释

        有节制地使用行内注释。 

        行内注释是与代码语句同行的注释。行内注释和代码至少要有两个空格分隔。注释由#和一个空格开始。 

        事实上,如果状态明显的话,行内注释是不必要的,反而会分散注意力。

        比如说下面这样就不需要:

                        x = x + 1                 # Increment x

        但有时,这样做很有用:

                        x = x + 1                 # Compensate for border

 

多行注释-文档字符串

        编写好的文档说明(也叫“docstrings”)的约定在PEP 257中永恒不变。

        要为所有的公共模块,函数,类以及方法编写文档说明。非公共的方法没有必要,但是应该有一个描述方法具体作用的注释。这个注释应该在def那一行之后。

        PEP 257 描述了写出好的文档说明相关的约定。特别需要注意的是,多行文档说明使用的结尾三引号应该自成一行,例如:

"""Return a foobang



Optional plotz says to frobnicate the bizbaz first.

"""

        对于单行的文档说明,尾部的三引号应该和文档在同一行。

 

多行注释-类和方法注释

        类和方法注释一般写在定义类的下方,如:

 

四、命名规范

        Python库的命名规范很乱,从来没能做到完全一致。但是目前有一些推荐的命名标准。新的模块和包(包括第三方框架)应该用这套标准,但当一个已有库采用了不同的风格,推荐保持内部一致性。

最重要的原则

        那些暴露给用户的API接口的命名,应该遵循反映使用场景而不是实现的原则。

描述:命名风格

        有许多不同的命名风格。这里能够帮助大家识别正在使用什么样的命名风格,而不考虑他们为什么使用。 

        以下是常见的命名方式:

  • b(单个小写字母)
  • B(单个大写字母)
  • 【推荐】lowercase 小写字母
  • 【推荐】 lower_case_with_underscores 使用下划线分隔的小写字母
  • UPPERCASE 大写字母
  • UPPER_CASE_WITH_UNDERSCORES 使用下划线分隔的大写字母
  • CapitalizedWords(或者叫 CapWords,或者叫CamelCase 驼峰命名法)。有时候也被称为StudlyCaps。 当在首字母大写的风格中用到缩写时,所有缩写的字母用大写,因此,HTTPServerError 比 HttpServerError 好。

        注意:仅class类名推荐

  • mixedCase(不同于首字母大写,第一个单词的首字母小写)
  • Capitalized_Words_With_Underscores(巨丑无比!)

 

        另外,下面这种用前缀或结尾下划线的特殊格式是被认可的(通常和一些约定相结合):

  • _single_leading_underscore:(单下划线开头)弱“内部使用”指示器。比如 from M import * 是不会导入以下划线开始的对象的。
  • single_trailing_underscore_:(单下划线结尾)这是避免和Python内部关键词冲突的一种约定,比如:Tkinter.Toplevel(master, class_=’ClassName’)
  • __double_leading_underscore:(双下划线开头)当这样命名一个类的属性时,调用它的时候名字会做矫正(在类FooBar中,__boo变成了_FooBar__boo;见下文)。
  • __double_leading_and_trailing_underscore__:(双下划线开头,双下划线结尾)“magic”对象或者存在于用户控制的命名空间内的属性,例如:__init__,__import__或者__file__。除了作为文档之外,永远不要命这样的名。

约定俗成:命名约定

                应避免的名字

                永远不要使用字母‘l’(小写的L),‘O’(大写的O),或者‘I’(大写的I)作为单字符变量名。 

                在有些字体里,这些字符无法和数字0和1区分,如果想用‘l’,用‘L’代替。

                包名和模块名

                模块应该用简短全小写的名字,如果为了提升可读性,下划线也是可以用的。Python包名也应该使用简短全小写的名字,但不建议用下划线。 

                当使用C或者C++编写了一个依赖于提供高级(更面向对象)接口的Python模块的扩展模块,这个C/C++模块需要一个下划线前缀(例如:_socket)

 

                类名

               类名一般使用首字母大写的约定。       

                在接口被文档化并且主要被用于调用的情况下,可以使用函数的命名风格代替。 

                注意,对于内置的变量命名有一个单独的约定:大部分内置变量是单个单词(或者两个单词连接在一起),首字母大写的命名法只用于异常名或者内部的常量。

                异常名

                因为异常一般都是类,所有类的命名方法在这里也适用。然而,你需要在异常名后面加上“Error”后缀(如果异常确实是一个错误)。

                全局变量名

                (我们希望这一类变量只在模块内部使用。)约定和函数命名规则一样。 

                通过 from M import * 导入的模块应该使用all机制去防止内部的接口对外暴露,或者使用在全局变量前加下划线的方式(表明这些全局变量是模块内非公有)。

                函数名

                函数名应该小写,如果想提高可读性可以用下划线分隔。

                大小写混合仅在为了兼容原来主要以大小写混合风格的情况下使用(比如 threading.py),保持向后兼容性。

                函数和方法参数

                始终要将 self 作为实例方法的的第一个参数。

                始终要将 cls 作为类静态方法的第一个参数。 

                如果函数的参数名和已有的关键词冲突,在最后加单一下划线比缩写或随意拼写更好。因此 class_ 比 clss 更好。(也许最好用同义词来避免这种冲突)

                方法名和实例变量

                遵循这样的函数命名规则:使用下划线分隔小写单词以提高可读性。 

                在非共有方法和实例变量前使用单下划线。 

                通过双下划线前缀触发Python的命名转换规则来避免和子类的命名冲突。 

                Python通过类名对这些命名进行转换:如果类 Foo 有一个叫 __a 的成员变量, 它无法通过 Foo.__a 访问。(执着的用户可以通过 Foo._Foo__a 访问。)一般来说,前缀双下划线用来避免类中的属性命名与子类冲突的情况。 

 

                常量

                常量通常定义在模块级,通过下划线分隔的全大写字母命名。例如: MAX_OVERFLOW 和 TOTAL。

 

                继承的设计

                始终要考虑到一个类的方法和实例变量(统称:属性)应该是共有还是非共有。如果存在疑问,那就选非共有;因为将一个非共有变量转为共有比反过来更容易。 

                公共属性是那些与类无关的客户使用的属性,并承诺避免向后不兼容的更改。非共有属性是那些不打算让第三方使用的属性;你不需要承诺非共有属性不会被修改或被删除。 

                我们不使用“私有(private)”这个说法,是因为在Python中目前还没有真正的私有属性(为了避免大量不必要的常规工作)。 

                另一种属性作为子类API的一部分(在其他语言中通常被称为“protected”)。有些类是专为继承设计的,用来扩展或者修改类的一部分行为。当设计这样的类时,要谨慎决定哪些属性时公开的,哪些是作为子类的API,哪些只能在基类中使用。 

                贯彻这样的思想,一下是一些让代码Pythonic的准则:

                公共属性不应该有前缀下划线。

                如果公共属性名和关键字冲突,在属性名之后增加一个下划线。这比缩写和随意拼写好很多。(然而,尽管有这样的规则,在作为参数或者变量时,‘cls’是表示‘类’最好的选择,特别是作为类方法的第一个参数。) 

                注意1:参考之前的类方法参数命名建议

                对于单一的共有属性数据,最好直接对外暴露它的变量名,而不是通过负责的 存取器(accessor)/突变(mutator) 方法。请记住,如果你发现一个简单的属性需要成长为一个功能行为,那么Python为这种将来会出现的扩展提供了一个简单的途径。在这种情况下,使用属性去隐藏属性数据访问背后的逻辑。

                注意1:属性只在new-style类中起作用。 

                注意2:尽管功能方法对于类似缓存的负面影响比较小,但还是要尽量避免。

                注意3:属性标记会让调用者认为开销(相当的)小,避免用属性做开销大的计算。

                如果你的类打算用来继承的话,并且这个类里有不希望子类使用的属性,就要考虑使用双下划线前缀并且没有后缀下划线的命名方式。这会调用Python的命名转换算法,将类的名字加入到属性名里。这样做可以帮助避免在子类中不小心包含了相同的属性名而产生的冲突。 

                注意1:只有类名才会整合进属性名,如果子类的属性名和类名和父类都相同,那么你还是会有命名冲突的问题。 

                注意2:命名转换会在某些场景使用起来不太方便,例如调试,__getattr__()。然而命名转换的算法有很好的文档说明并且很好操作。

                注意3:不是所有人都喜欢命名转换。尽量避免意外的名字冲突和潜在的高级调用。

 

        公共和内部的接口

        任何向后兼容保证只适用于公共接口,因此,用户清晰地区分公共接口和内部接口非常重要。

        文档化的接口被认为是公开的,除非文档明确声明它们是临时或内部接口,不受通常的向后兼容性保证。所有未记录的接口都应该是内部的。 

        为了更好地支持内省(introspection),模块应该使用__all__属性显式地在它们的公共API中声明名称。将__all__设置为空列表表示模块没有公共API。 

        即使通过__all__设置过,内部接口(包,模块,类,方法,属性或其他名字)依然需要单个下划线前缀。 

        如果一个命名空间(包,模块,类)被认为是内部的,那么包含它的接口也应该被认为是内部的。 

        导入的名称应该始终被视作是一个实现的细节。其他模块必须不能间接访问这样的名称,除非它是包含它的模块中有明确的文档说明的API,例如 os.path 或者是一个包里从子模块公开函数接口的 __init__ 模块。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值