您的位置:首页 > 编程语言

PEP 8 代码规范

2016-02-21 16:08 246 查看

代码排版

缩进

每层缩进使用四个空格

续行要么与圆括号、中括号、花括号这样的被包裹元素保持垂直对齐,要么放在 Python 的隐线(注:应该是相对于def的内部块)内部,或者使用悬挂缩进5。使用悬挂缩进的注意事项:第一行不能有参数,用进一步的缩进来把其他行区分开。

# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
var_three, var_four)

# More indentation included to distinguish this from the rest.
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)

# Hanging indents should add a level.
foo = long_function_name(
var_one, var_two,
var_three, var_four)


如果if语句过长,需要将其写入多行

# No extra indentation(缩进).
if (this_is_one_thing and
that_is_another_thing):
do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
that_is_another_thing):
# Since both conditions are true, we can frobnicate.
do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
and that_is_another_thing):
do_something()


在多行结构中的右圆括号、右中括号、右大括号应该放在最后一行的第一个非空白字符的正下方,如下所示:

my_list = [
1, 2, 3,
4, 5, 6,
]




my_list = [
1, 2, 3,
4, 5, 6,
]


制表符还是空格

空格是首选的缩进方法

python3 不允许混合使用制表符和空格

每行最大长度

根据团队的不同长度也不一,80~100都是可以接受的。我们规定每行长度为100

首选的换行方式是隐式换行(如上),也可以使用 “\”来进行换行

空行

顶级函数和类定义上下使用两个空行分割,类内的方法定义使用一个空行分割。

可以使用额外的空行(有节制的),来分割相关联的函数组。在一系列相关联的单行代码中空行可以省略。

在函数中使用空白行(有节制的)来表明逻辑部分。

导包

import 不同的模块应该独立一行

imoprt 语句应该总是放在文件的顶部,在模块注释和文档字符串之下,在模块的全局变量和常量之前

import语句分组顺序

导入标准库模块

导入第三方库模块

导入当前程序/库模块

每组之间用空行隔开

绝对导入是推荐的,他们通常是更可读的,并且在错误的包系统配置下有良好的行为倾向

从一个包含类的模块导入类的时候,这样通常是可行的

from myclass import MyClass
from foo.bar.yourclass imoprt YourClass


避免使用通配符导入,这样会使得命名空间不清晰

字符串引号

在python中单引号和双引号的字符串是相同的,我们推荐双引号

表达式和语句中的空格

Yes: spam(ham[1], {eggs: 2})
No:  spam( ham[ 1 ], { eggs: 2 } )


Yes: if x == 4: print x, y; x, y = y, x
No:  if x == 4 : print x , y ; x , y = y , x


yes: ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
no: ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]


Yes: spam(1)
No:  spam (1)
Yes: dct['key'] = lst[index]
No:  dct ['key'] = lst [index]


在复制操作符(或其他)的两侧保持多余一个的空格

x = 1
y = 2
long_variable = 3


其他建议

总是在这些二元操作符的两侧加入一个空格 (=,+=,-=,==,<, >, !=, <>,<=, >=, in, not in, is, is not, and , or , not )

在不同优先级之间,考虑在更低优先级的操作符两侧插入空格,用自己的判断力,但是不要使用超过一个空格,并且在二元操作符的两侧有着相同的空格数

不要在关键值参数或者默认值参数的等号两边加入空格

yes:def complex(real, imag=0.0):
return magic(r=real, i=imag)
no: def complex(real, imag = 0.0):
return magic(r = real, i = imag)


【注:Python 3】带注释的函数定义中的等号两侧要各插入空格。此外,在冒号后用一个单独的空格,也要在表明函数返回值类型的->左右各插入一个空格。

def munge(input: AnyStr):
def munge(sep: AnyStr = None):
def munge() -> AnyStr:
def munge(input: AnyStr, sep: AnyStr = None, limit=1000):


不要使用符合语句

no: if foo == 'blah': do_blah_thing()
do_one(); do_two(); do_three()


有时候把 if/for/while 和一个小的主体放在同一行也是可行的,千万不要在有多条语句的情况下这样做。此外,还要避免折叠,例如长行。

命名约定

覆盖原则

API 里对用户可见的公共部分应该遵循约定,反映的是使用而不是实现。

规定: 命名约定

有许多不同的命名风格,这有助于识别正在使用的命名风格,独立于他们的用途

应该避免的名字

永远不要使用单个字符l(小写字母 el),O(大写字母 oh),或I(大写字母 eye)作为变量名。

在一些字体中,这些字符是无法和数字1和0区分开的。试图使用l时用L代替。

包和模块名

模块名应该短,且全小写。如果能改善可读性,可以使用下划线。Python 的包名也应该短,全部小写,但是不推荐使用下划线。

因为模块名就是文件名,而一些文件系统是大小写不敏感的,并且自动截断长文件名,所以给模块名取一个短小的名字是非常重要的 – 在 Unix 上这不是问题,但是把代码放到老版本的 Mac, Windows,或者 DOS 上就可能变成一个问题了。

类名

类名通常使用capswords(骆驼命名法)约定

The naming convention for functions may be used instead in cases where the interface is documented and used primarily as a callable.

注意和内建名称的区分开:大多数内建名称是一个单独的单词(或两个单词一起),CapWords 约定只被用在异常名和内建常量上。

例: CapitalizedWords

异常名

因为异常应该是类,所以类名约定在这里适用。但是,你应该用Error作为你的异常名的后缀(异常实际上是一个错误)。

函数名

函数名应该是小写的,有必要的话用下划线来分隔单词提高可读性。

混合大小写仅仅在上下文都是这种风格的情况下允许存在(如thread.py),这是为了维持向后兼容性。

函数和方法参数

总是使用self作为实例方法的第一个参数。

总是使用cls作为类方法的第一个参数。

如果函数参数与保留关键字冲突,通常最好在参数后面添加一个尾随的下划线,而不是使用缩写或胡乱拆减。因此class_比clss要好。(或许避免冲突更好的方式是使用近义词)

方法名和实例变量

用函数名的命名规则:全部小写,用下划线分隔单词提高可读性。

用一个且有一个前导的下划线来表明非公有的方法和实例变量。

为了避免与子类变量或方法的命名冲突,用两个前导下划线来调用 Python 的命名改编规则。

Python 命名改编通过添加一个类名:如果类Foo有一个属性叫__a,它不能被这样Foo.__a访问(执着的人可以通过这样Foo._Foo__a来访问)通常,双前导的下划线应该仅仅用来避免与其子类属性的命名冲突。

常量

常量通常是模块级的定义,全部大写,单词之间以下划线分隔。例如MAX_OVERFLOW和TOTAL。

程序编写建议

代码的编写方式不能对其它 Python 的实现(PyPy、Jython、IronPython、Cython、Psyco,诸如此类的)不利。

例如,不要依赖于 CPython 在字符串拼接时的优化实现,像这种语句形式a += b和a = a + b。即使是 CPython(仅对某些类型起作用) 这种优化也是脆弱的,不是在所有的实现中都不使用引用计数。在库中性能敏感的部分,用”.join形式来代替。这会确保在所有不同的实现中字符串拼接是线性时间的。

比较单例,像None应该用is 或者is not 从不使用==操作符

用 is not 操作符号而不是not … is

前一个更加可读

用富比较实现排序操作的时候,实现所有六个比较操作符( __eq__ 、 __ne__ 、 __lt__ , __le__ , __gt__ , __ge__)是更好的,而不是依赖其它仅仅运用一个特定比较的代码

始终使用def语句来代替直接绑定了一个lambda表达式的赋值语句。

yes:  def f(x): return 2*x
no :  f = lambda x: 2*x


第一种形式意味着函数对象的名字是’f’而不是’’的。通常这对异常追踪和字符串表述是更有用的。使用赋值语句消除的唯一好处,
lambda
表达式可以提供一个显示的
def
语句不能提供的,如,
lambda
能镶嵌在一个很长的表达式里。

异常类应派生自Exception而不是BaseException。直接继承自BaseException是为Exception保留的,如果从BaseException继承,捕获到的错误总是错的。

适当的使用异常链。在 Python 3 里,raise X from Y用于表明明确的替代者,不丢失原有的回溯信息。

在 Python 2 里抛出异常时,用raise ValueError(‘message’)代替旧式的raise ValueError, ‘message’。

捕获异常时,尽可能使用明确的异常,而不是用一个空的except:语句。

一个空的except:语句将会捕获到SystemExit和KeyboardInterrupt异常,很难区分程序的中断到底是Ctrl+C还是其他问题引起的。如果你想捕获程序的所有错误,使用except Exception:(空except:等同于except BaseException)。

一个好的经验是限制使用空except语句,除了这两种情况:

如果异常处理程序会打印出或者记录回溯信息;至少用户意识到错误的存在。

如果代码需要做一些清理工作,但后面用raise向上抛出异常。try .. finally是处理这种情况更好的方式。

坚持使用return语句。函数内的return语句都应该返回一个表达式,或者None。如果一个return语句返回一个表达式,另一个没有返回值的应该用return None清晰的说明,并且在一个函数的结尾应该明确使用一个return语句(如果有返回值的话)。

用字符串方法代替字符串模块

用”.startswith()和”.endswith()代替字符串切片来检查前缀和后缀。

对象类型的比较应该始终使用isinstance()而不是直接比较

Yes: if isinstance(obj, int):
No:  if type(obj) is type(1):


注意:

* 当比较一个对象是不是字符串时,记住它有可能也是一个 unicode 字符串!在 Python 2 里面,str和unicode有一个公共的基类叫basestring,因此你可以这样做:*

if isinstance(obj, basestring):


对于序列(字符串、列表、元组)来说,空的序列为False:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python PEP-8