PEP8

2018-06-12  本文已影响0人  HammurabiCode

代码布局

缩进

推荐的两种方式:

建议


# 垂直对齐,与外面(), [], {}对齐
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# 悬挂缩进,以行开头作为参考
foo = long_function_name(
    var_one, var_two,
    var_three, var_four)
    
    
# 为了和函数体区分开,采用更多的缩进
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

不建议

# 如果使用悬挂缩进而不是垂直对齐,第一行就不要有参数。
foo = long_function_name(var_one, var_two,
    var_three, var_four)

# 
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

括号结束的处理

# 和上一行的第一个不为空格的字符对齐
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
    )
# 和语句开头的第一个字符对齐
my_list = [
    1, 2, 3,
    4, 5, 6,
]

if语句的缩进

# 无额外的缩进.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# 添加一条注释来分隔if语句的两个部分
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# 添加额外的缩进来分隔if语句的两个部分
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

Tab还是空格

单行的最大长度

79个字符。

对于docstring和注释:72个字符。

好处:

实践:

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())

换行到底在二元操作符前面还是后面?

# No: operators sit far away from their operands
income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends) -
          ira_deduction -
          student_loan_interest)

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

空行

文件编码

UTF-8

import语句

# Yes: 
import os
import sys

# No:
import sys, os

# OK:
from subprocess import Popen, PIPE

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

# 如果类名有冲突
import myclass
import foo.bar.yourclass

# 使用时:"myclass.MyClass"  "foo.bar.yourclass.YourClass".

模块级的dunder name

模块级的dunder name,比如__all__, __version__, __author__应该放在import之前,但是在from __future__ import之后,因为这一句是强制要求在所有代码之前的。

"""This is the example module.

This module does stuff.
"""

from __future__ import barry_as_FLUFL

__all__ = ['a', 'b', 'c']
__version__ = '0.1'
__author__ = 'Cardinal Biggles'

import os
import sys

字符串的引号

单引号双引号都可以,那么选择一个,然后保持一致。

表达式和语句中的空格

一定不要这么做!

# Yes: 
spam(ham[1], {eggs: 2})
foo = (0,)

# No:  
spam( ham[ 1 ], { eggs: 2 } )
bar = (0, )
# 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)
foo = (0, 1)

# No:
spam (1)
# Yes: 
dct['key'] = lst[index]
# No:  
dct ['key'] = lst [index]
# Yes:
x = 1
y = 2
long_variable = 3

# No:
x             = 1
y             = 2
long_variable = 3

其他的建议

# 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)
# Yes:
def munge(sep: AnyStr = None): ...
def munge() -> AnyStr: ...
def munge(input: AnyStr, sep: AnyStr = None, limit=1000): ...
# No:
def munge(input: AnyStr=None): ...
def munge()->PosInt: ...
def munge(input: AnyStr, limit = 1000): ...

什么时候使用结尾的逗号

# Yes:
FILES = ('setup.cfg',)

# OK
FILES = 'setup.cfg',
# Yes:
FILES = [
    'setup.cfg',
    'tox.ini',
    ]
initialize(FILES,
           error=True,
           )

# No:
FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)

注释

行内注释

文档字符串 docstrings

"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.
"""

命名规范

让所有代码都遵守一致的命名规范很难的,可以要求新的模块和包遵守一定的规范,但已有的库可能不满足,这时候需要在内部保持一致。

首要原则

对外的接口,要反映usage,而不是implementation

常见的命名方式

规范

继承的设计

公共接口和内部接口

编程建议

# Yes:
if foo is not None:
    ...
# No:
if not foo is None:
    ...
try:
    foo()
expect Exception as exc:
    print(exc)

自动格式化的工具

black

如何处理折行?

1. 尝试不折行
2. 打开最外层括号,括号内内容单独一行
3. 还是不行,迭代打开括号
4. 如果内容没有括号,有逗号做分隔,尝试同一行
5. 放不下->每一项独占一行,并加一个多于的逗号。(便于diff)
# in:

def very_important_function(template: str, *variables, file: os.PathLike, debug: bool = False):
    """Applies `variables` to the `template` and writes to `file`."""
    with open(file, 'w') as f:
        ...

# out:

def very_important_function(
    template: str,
    *variables,
    file: os.PathLike,
    debug: bool = False,
):
    """Applies `variables` to the `template` and writes to `file`."""
    with open(file, "w") as f:
        ...

行的长度

默认88,为了让文件长度更短。
尺有所短寸有所长。

空行

遵循PEP8

tailing commas

isort

自动给import语句排序。

静态代码分析工具

pycodestyle

原名pep8。参照PEP 8。定义了Error codes

Pylint
flake8

formatter

yapf
black
autopep8
上一篇 下一篇

猜你喜欢

热点阅读