个人Python代码规范【长期更新】

记录一下自己的代码规范以供随时查看,也给看到的网友一个参考,如有不足之处,欢迎批评讨论。代码规范主要参考了PEP 8 – Python代码风格指导谷歌Python风格指导和PyCharm默认代码风格,也有一些自己的微小改动(若有会指出)和补充的地方。

目录

代码布局

缩进

每行最大长度

空行

源文件编码

模块引用

字符串引用

表达式和语句中的空格

末尾添加逗号

注释

文档字符串

命名约定

命名风格

命名约定

编程建议

类型注解


代码布局

缩进

每一级缩进使用4个空格,但考虑到每次缩进都要按四次空格太麻烦了,所以本人还是使用Tab键缩进,但要在IDE中检查是否将缩进指定为4个空格:

续行时如果括号前的内容较短则采用隐式续行,即元素垂直对齐于圆括号、方括号或花括号;如果括号前的内容较长则采用悬挂缩进,即在续行中再缩进一级即可,无须对齐括号,同时第一行不应该包含参数:

# 隐式续行,第二行同开始分界符(左括号)对齐
foo = function_name(var_one, var_two,
                    var_three, var_four)


# 悬挂缩进,续行多缩进一级以同其他代码区别,同时首行不包含参数
def long_long_long_long_long_long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

当if语句的条件部分长到需要换行写的时候,续行额外增加一级缩进:

# 在if语句的续行中额外增加一级缩进以区分判断和执行
if (this_is_one_thing and
        that_is_another_thing):
    do_something()

多行结束的右括号可以为了美观单独写一行,和首行第一个字符对齐:

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

每行最大长度

PEP8推荐每行代码的最大字符数限制为79,文档或注释则限制为72,以方便分屏查看代码。但实际使用时单行代码很容易超过该限制,尤其是代码逻辑层数较多、前面有大段缩进时,此时频繁强制换行容易降低代码可读性:

 故本人建议将最大字符数限制为120(ps:120不够用,现在设成了140),方法如下:

1.取消勾选使用Black格式化程序;2.将强制换行位置修改为120并点击应用。

 

 单行代码超过最大字符数限制的解决方法:将表达式用小括号括起来再用隐式续行,无法使用小括号的情况下用反斜杠续行:

# 使用小括号和隐式续行
result = (long_expression
          + another_long_expression)

# 使用反斜杠续行
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())

表达式换行在二元运算符之前换,以使运算符更贴近操作数:

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

空行

顶层函数和类的定义用两个空行隔开。类中的方法定义用一个空行隔开,可以使用额外的空行(尽量少)来分隔相关的函数组。在一组相关的、仅占一行的函数之间,可以不空行。可以在函数内使用空行(尽量少)区分逻辑段。

# 顶层函数和类的定义用两个空行隔开。
# 可以在函数内使用空行(尽量少)区分逻辑段。
def top_level_function():
    # 第一段逻辑
    do_something()
    do_something_else()

    # 第二段逻辑
    do_something_more()
    do_something_else_more()


# 类中的方法定义用一个空行隔开,可以使用额外的空行(尽量少)来分隔相关的函数组。
# 在一组相关的、仅占一行的函数之间,可以不空行。
class MyClass:
    def method_one(self):
        pass

    def method_two(self):
        pass


    def method_a(self):pass
    def method_b(self):pass
    def method_c(self):pass

源文件编码

PEP8推荐代码和注释中尽量只使用ASCII编码,但考虑到对中文字符的使用需求,本人遵循的原则是:在代码中所有标识符只使用ASCII编码,但字符串文字和注释可以使用非ASCII编码。

# 正确示例:标识符只使用ASCII编码,字符串文字和注释可以使用非ASCII编码
result = 'ASCII string ' + '非ASCII字符串'  # 注释

# 错误示例:标识符使用非ASCII编码
结果 = 'ASCII string ' + '非ASCII字符串'

模块引用

import应该写在代码文件的开头,位于模块注释和文档字符串之后,模块全局变量和常量声明之前。引用不同的模块要分行写,但引用同一个模块下的不同内容可以写在一行。import应该按以下顺序分组写:1.标准库;2.第三方库;3.本地库。不同组之间用空行隔开。

引用范围应该尽量小,在不啰嗦的情况下尽量用from <module> import代替import <module>,没有特殊原因不使用通配符import(from <module> import *)。

模块中的双下划线变量(变量名以两个下划线开头,两个下划线结尾),比如__all__,__author,__version__等,应该写在文档字符串之后,除form __future__ imports的任何其它类型的引用语句之前。

"""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
from subprocess import Popen, PIPE

from pandas import DataFrame, Series

from my_module import some_function

字符串引用

正常情况下只使用单引号表示字符串,但当字符串中包含单引号时,则采用双引号来表示字符串。用三个双引号使用三引号。

# 正常情况下只使用单引号表示字符串
name = 'Alice'

# 当字符串中包含单引号时,则采用双引号来表示字符串
message = "Don't worry, be happy!"

# 用三个双引号使用三引号
docstring = """This is a multi-line string.
It can span multiple lines and contain "double quotes"."""

表达式和语句中的空格

添加空格的规则太麻烦了,建议在编写代码时统一不加空格,编写完成后使用“重新格式化代码”功能自动添加空格。

末尾添加逗号

在定义单元素元组时末尾必须加逗号,其他情况下尽量不在末尾加逗号,除非是为将来有可能的扩展预留冗余。

#定义单元素元组时末尾必须加逗号
FILE = ('setup.cfg',)

#为将来有可能的扩展预留冗余的逗号
FILES = [
    'setup.cfg',
    'tox.ini',
]
initialize(FILES,
           error=True,
           )

注释

注释以#和一个空格开头,应该是完整的多个句子,并且以句号结尾。如果注释很短句号可以忽略。块注释写在对应代码之前,并且和对应代码有同样的缩进级别。尽量少用行内注释,如果用注释和代码语句之间有两个空格的间隔。

# 短注释
if condition:
    # 这是一个块注释。
    # 包含了多行文字。
    x = x + 1  # 边界补偿

文档字符串

所有的公共模块,函数,类和方法都应该有文档字符串,该字符串位于声明的下一行,并且以单行"""结尾。

def my_function():
    """文档字符串在声明的下一行,并且以单行三引号结尾。
    """

命名约定

首要原则:用户可见的公共部分API,其命名应当表达出功能用途而不是具体的实现细节。

命名风格

命名使用带下划线小写的风格:lower_case_with_underscores。

以下划线开始或结尾的特殊形式有特定功能:

_single_leading_underscore: 以单个下划线开头是”内部使用”的弱标志。

single_trailing_underscore_: 以单个下划线结尾用来避免和Python关键词产生冲突。

__double_leading_underscore: 以双下划线开头的风格命名类属性表示触发命名修饰。

__double_leading_and_trailing_underscore__: 以双下划线开头和结尾的命名风格表示“魔术”对象或属性,用于重写以实现特定功能。

命名约定

全小写带下划线:模块名,函数名,变量名

全小写不带下划线:包名

驼峰命名法:类名(异常名若要抛出错误应加上Error后缀),类型变量名

全大写带下划线:常量名

禁止使用:单个字符’l’(L的小写的字母),’O’(o大写的字母),’I’(i的大写的字母)。

编程建议

代码应该以不影响其他Python实现(PyPy,Jython,IronPython,Cython,Psyco等)的方式编写。

None应该用is或is not作比较,不要使用==操作符。

用is not操作符而不是not ... is。

用富比较实现排序操作的时候,最好实现所有六个比较操作符( __eq__ 、 __ne__ 、 __lt__ , __le__ , __gt__ , __ge__),而不是依靠其他代码来进行特定比较。为了最大限度减少工作量,functools.total_ordering()装饰器提供了一个工具去生成缺少的比较方法。

不要通过赋值语句将lambda表达式绑定到一个变量上来定义函数。

异常类应派生自Exception而不是BaseException。

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

对于所有try / except子句,将try子句限制为必需的绝对最小代码量,以避免屏蔽错误。

当某个资源仅被特定代码段使用时,用with语句确保其在使用后立即释放资源。

在函数中默认返回None的位置显式地指出return None。

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

不要让字符串对尾随的空格有依赖。

不要用==比较True和False。

类型注解

typing —— 对类型提示的支持

  • 11
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值