Python 代码规范

参考文章链接

https://www.python.org/dev/peps/pep-0008/

Python编码规范(Style Guide for Python Code)_L-CSDN博客

重新学习python

代码布局

缩进

每个缩进级别使用 4 个空格。

方式一:

# 与开始分隔符对齐。

foo = long_function_name(var_one, var_two,
                         var_three, var_four)

方式二:

# 添加 4 个空格(额外的缩进级别)以将参数与其他参数区分开来。

def 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):
    打印(var_one)

if语句

当if语句的条件部分足够长以要求将其写成多行时,值得注意的是,两个字符的关键字(即if)、单个空格和左括号的组合创建了一个自然的多行条件的后续行的 4 个空格缩进。这可能会与嵌套在if语句中的缩进代码套件产生视觉冲突,该代码也自然会缩进 4 个空格。

# 没有额外的缩进。
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# 添加注释,这将在编辑器中提供一些区别
# 支持语法突出显示。
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# 在条件续行上添加一些额外的缩进。
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

if 语句的缩进不限于以上内容。

括号(大括号、方括号、圆括号)

多行结构上的右大括号/方括号/圆括号可以排列在列表最后一行的第一个非空白字符下,如下所示:

my_list = [ 
    1, 2, 3, 
    4, 5, 6, 
    ] 
result = some_function_that_takes_arguments( 
    'a', 'b', 'c', 
    'd', 'e', 'f', 
    )

或者它可以排列在开始多行结构的行的第一个字符下,如下所示:

my_list = [ 
    1, 2, 3, 
    4, 5, 6, 
] 
result = some_function_that_takes_arguments( 
    'a', 'b', 'c', 
    'd', 'e', 'f', 
)

注:

空格是首选的缩进方法。

制表符应仅用于与已使用制表符缩进的代码保持一致。

Python 不允许混合使用制表符和空格进行缩进。

最大行宽

每行长度限制为 72 个字符。可以使用反斜杠进行延续。

应该在二次运算符之前还是之后换行?

前后都可以,推荐在后。

income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

空行

用两个空行包围顶级函数和类定义。

类中的方法定义被一个空行包围。

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

在函数中谨慎使用空行来指示逻辑部分。

Python 接受 control-L(即 ^L)换页符作为空格;

源文件编码

核心 Python 发行版中的代码应始终使用 UTF-8,并且不应有编码声明。

Imports

导入通常应该在不同的行上,例如:

# 正确:
import os 
import sys
from elasticsearch import Elasticsearch

不推荐使用以下方式:

# 错误:
import os 
import sys
from elasticsearch import Elasticsearch

不过可以:

#正确
from common import text_similarity, getNextValue

imports总是放在文件的顶部,就在任何模块注释和文档字符串之后,以及模块全局变量和常量之前。

imports应按以下顺序分组:

  1. 标准库导入。
  2. 相关的第三方进口。
  3. 本地应用程序/库特定导入。

应该在每组导入之间放置一个空行。

模块级“Dunders”名称

“Dunders”名称:带有两个前导下划线和两个后置下划线的名称,例如: __all__, __author__, __version__等等。应当放在模块文档(module docstring)之后,所有import语句之前(from __future__ imports除外,from __future__ imports放在模块文档之后,所有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

字符串引用(String Quotes)

在Python中,单引号和双引号是一样的。本PEP不推荐这样,而是选择其中一条并坚持使用。当字符串中包含单引号和双引号时,使用另外一个避免反斜杠的转义。

表达式和语句中的空格

圆括号,中括号,大括号内部没有空格,如下:

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

逗号和小括号之间没有空格,如下: 

推荐: 
        foo = (0,)
不推荐:  
        bar = (0, )

逗号,分号,冒号之前没有空格,如下:

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

不用为了赋值符号对齐而使用多个空格,如下:

推荐:
 
x = 1
y = 2
long_variable = 3
不推荐:
x             = 1
y             = 2
long_variable = 3

注释(Comments)

        与代码冲突的注释比没有注释更糟糕。当代码发生变化时,始终优先保持注释的更新。注释应该是完整的句子,第一个单词应该大写,除非它是一个以小写字母开头的标识符(永远不要改变标识符的大小写!)。来自非英语国家的Python程序员:请用英语写您的注释,除非您有120%的信心这些代码永远不会被不使用您的语言的人阅读。

块注释(Block Comments)

        块注释一般使用在几行代码之前,与代码缩进相同,每行使用#开始,注释内容和#之间有一个空格,例如:

# The SAG solver releases the GIL so it's more efficient to use
# threads for this solver.
if self.solver in ['sag', 'saga']:
    backend = 'threading'
else:
    backend = 'multiprocessing'

如果注释分多个段落,段落之间使用单个#分隔,例如:

# The SAG solver releases the GIL so it's more efficient to use
#
# threads for this solver.
if self.solver in ['sag', 'saga']:
    backend = 'threading'
else:
    backend = 'multiprocessing'

行内注释(Inline Comments)

        内联注释是与语句在同一行上的注释。尽量少用行内注释。语句与行内注释之间至少两个空格或更多,#和注释内容之间一个空格,如下:

x = x + 1                 # Compensate for border

文档字符串(Documentation Strings

        Documentation Strings也称为docstrings。为所有公共模块、函数、类和方法编写文档字符串。对于非公共方法,docstring不是必需的,但是应该有一个描述该方法功能的注释。这个注释应该出现在def行之后。描述良好的文档字符串约定:结束多行docstring的三个双引号"""应该单独在一行上,例如:

"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""

对于单行docstring,三个双引号"""应该在与文档字符串在同一行上,例如:

def kos_root():
    """Return the pathname of the KOS root directory."""
    global _kos_root
    if _kos_root: return _kos_root
    ...

命名约定(Naming Conventions)

        Python库的命名约定有点混乱,所以我们永远不会得到完全一致的结果——尽管如此,下面是目前推荐的命名标准。应该按照这些标准编写新的模块和包(包括第三方框架),但是如果现有库具有不同的风格,则最好采用内部一致性。

几种命名风格:

单个小写字符:b

单个大写字符:B

小写单词:age

大写单词:NAME

下划线连接小写单词:lower_case_with_underscores

下划线连接大写单词:UPPER_CASE_WITH_UNDERSCORES

驼峰命名(每个单词首字母大写):CapitalizedWords

每个单词首字母大写(第一个单词首字母小写):mixedCase 

另外,使用前导或后置下划线的特殊格式:

(1)_single_leading_underscore:前面添加单个下划线表示内部使用,例如:import语句from M import *不会导入单个下划线开始的对象。

(2)single_trailing_underscore_:后面添加单个下划线避免与关键字冲突,例如:

                            Tkinter.Toplevel(master, class_='ClassName')

(3)__double_leading_underscore:命名类属性时使用双下划线开头。

(4)__double_leading_and_trailing_underscore__:前后使用双下划线,用于命名空间中的魔法(“magic”)对象和属性。例如:__init__, __import__ or __file__,永远不要发明这样的名字;只在文档中使用它们。

不要使用“l”,“O”,“i”等作为单个字符变量的名字,因为有时它们无法与数字“1”和“0”区分。

包和模块名

模块名字全部小写,可以使用下划线连接。

Python包也全部使用小写字母,不推荐使用下划线连接。

When an extension module written in C or C++ has an accompanying Python module that provides a higher level (e.g. more object oriented) interface, the C/C++ module has a leading underscore (e.g. _socket).

类名称(Class Names

类名使用驼峰命名法。

类型变量名称(Type Variable Names

PEP 484中引入的类型变量的名称通常应该使用驼峰命名法,它们更喜欢短名称:T、AnyStr、Num。建议在用于声明协变或逆变行为的变量中添加后缀_co或_contra,例如:

 
​
from typing import TypeVar

VT_co = TypeVar('VT_co', covariant=True)

KT_contra = TypeVar('KT_contra', contravariant=True)

异常名称(Exception Names)
​

异常也是一个类,使用驼峰命名法,但是应当添加“Error”后缀。

全局变量名称(Global Variable Names

我们希望这些变量只在一个模块中使用。

函数和变量名称(Function and Variable Names

函数名和变量名使用小写字母,单词之间使用下划线。变量命名和函数相同。mixedCase只允许在已经是主流样式的上下文中使用(例如thread .py),以保持向后兼容性。

函数和方法参数(Function and Method Arguments

(1)实例方法:始终使用self作为第一个参数;

(2)类方法:始终使用cls作为第一个参数;

如果函数参数的名称与保留关键字冲突,通常最好附加一个尾随下划线,而不是使用缩写或拼写错误。因此class_比clss好。(或许更好的办法是使用同义词来避免这种冲突。)

方法名称和实例变量(Method Names and Instance Variables

(1)和函数名称命名规定相同

(2)仅对非公共方法和实例变量使用一个前导下划线

常量(Constants

常量通常在模块级别上定义,并使用大写字母和下划线分隔单词。例如MAX_OVERFLOW和TOTAL。

继承的设计(Designing for Inheritance

总是决定类的方法和实例变量(统称:“属性”)是公共的还是非公共的。如有疑问,选择非公开;稍后将其公开比将公共属性设置为非公共更容易。我们在这里不使用术语“私有”,因为在Python中没有真正私有的属性。

(1)公共属性应该没有前导下划线

(2)如果公共属性名与保留关键字冲突,请在属性名后面追加一个下划线

(3)如果类打算被子类化,并且不希望子类使用的属性,那么可以考虑使用双前导下划线和无后置下划线来命名它们。

公共接口和内部接口(Public and Internal Interfaces

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


设计推荐(Programming Recommendations

(1)代码的编写方式应该不影响Python的其他实现(PyPy、Jython、IronPython、Cython、Psyco等)。例如,不依赖CPython的高效实现就地字符串连接的语句形式+ = b或a = a + b。这种优化是脆弱的甚至在CPython的(只适用于某些类型)和不存在在不使用refcounting实现。在库的性能敏感部分,应该使用“.join()表单”。这将确保在不同实现之间以线性时间进行连接。

(2)使用 is not 而不是not…is。虽然这两个表达式在功能上是相同的,但前者更易于阅读和首选。

(3)与None之类的单例进行比较时,应该始终使用is或is not而不是相等运算符。

(4)在实现具有丰富比较的排序操作时,最好实现所有6个操作(__eq__、__ne__、__lt__、__le__、__gt__、__ge__),而不是依赖其他代码只执行特定的比较。

(5)始终使用def语句,而不是直接将lambda表达式绑定到标识符的赋值语句。

 
推荐:


def f(x): return 2*x


不推荐:


f = lambda x: 2*x

(6)捕获异常时,尽可能地提到特定的异常,而不是使用空的except:子句

 
try:

import platform_specific_module

except ImportError:

platform_specific_module = None

(7)不要使用==将布尔值与True或False进行比较。

 
Yes: if greeting:

No: if greeting == True:

Worse: if greeting is True:

(8)对于序列(字符串、列表、元组),使用空序列为假的事实

Yes: if not seq:

if seq:


No: if len(seq):

if not len(seq):

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

Yes: if isinstance(obj, int):


No: if type(obj) is type(1):

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值