Python----Python编码规范

简介: Python----Python编码规范

【原文链接】

一、布局

1.1 缩进

  • 每一级缩进使用4个空格
  • 类似定义函数或者调用函数时参数过多的场景,有两种推荐缩进做法,一种是第一行有参数,换行后利用

括号默认的垂直对齐方式。另一种方式就是第一行没有参数,参数直接换行到下一行,此时
缩进需要比其他代码多缩进一级,便于轻松识别出不是其他的代码语句

  • if语句中条件比较多需要换行时,推荐两种处理方式,一种是判断条件和代码之间

增加一行注释,另外一种就是对条件做更多一层的缩进,从而用于语句块中的代码区分开

  • 当多行结构中使用的括号(小括号、方括号、花括号)的右括号另起一行的时候,可以与上一行的第一个字符对齐

或者也可以与下一行的第一个字符对齐

# 以下代码为推荐代码:
def long_function_name(var_one,
                   var_two, 
                   var_three,
                   var_four):
    print(var_one)
  
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)
  
foo = long_function_name(
    var_one, var_two,
    var_three, var_four)

if (this_is_one_thing and
    that_is_another_thing):
    # 当满足某种条件时执行此分支.
    do_something()
  
if (this_is_one_thing
        and that_is_another_thing):
    do_something()
  
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',
)

# 以下代码为不推荐代码
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)
  
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

1.2 Tabs 键还是 空格键

  • 空格是首选的缩进方式
  • 如果使用tab键则所有缩进均需要使用tab键
  • python3不允许同时使用空格和tab键

1.3 行最大长度

  • 所有行限制最大字符数为79
  • 注释、字符串等文本行最大字符数限制72
  • 如果团队内达成一致认识,可以将代码行最大长度扩大到99,注释行仍然限制72
  • 一行代码过长时优先通过小括号,方括号,花括号来换行,而不是反斜线的方式

    # 推荐做法
      def methond_to_show_code_set_in_multiline_with_bracket(first_paramp="",
                                                        second_param="",
                                                        third_param=""):
         pass
             
    # 不推荐做法
     def methond_to_show_code_set_in_multiline_with_bracket(first_paramp="",\
                                                        second_param="",\
                                                        third_param=""):
         pass

1.4 在二元运算符之前还是之后换行呢?

  • 在很长的表示式中如果想换行推荐在二元操作符之前换行

    # 推荐做法
    income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)
    
    # 不推荐做法
    income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends) -
          ira_deduction -
          student_loan_interest)

1.5 空行

  • 文件顶级的类或者函数定义的前后需要使用两个空行
  • 类中方法定义前后使用一个空行
# 注释

def func1():
    pass


class Demo1():

    def method1(self):
    pass

    def method2(self):
    pass


def func2():
    pass


class Demo2():
    pass

1.6 源文件编码

  • 文件中不应有编码声明,默认均以UTF-8编码

1.7 imports

  • 不同的包在不同的行导入,不推荐一行导入多个包
  • 一行可以导入同一个包中的多个模块或类
  • 导入总是文件的顶部,在模块注释和文档字符串之后,在模块的全局变量和常量之前
  • 导入应该按照如顺序导入,在每一组中间需要加入空行
  • 标准库导入
  • 第三方库导入
  • 本地应用库导入
  • 推荐使用绝对路径导入,可读性更好
  • 避免使用通配符导入,如from xxx import *

    # 推荐做法
    import os
    import sys
    from subprocess import Popen, PIPE
    
    from flask import Flask
    
    # 不推荐做法
    import os,sys
    from subprocess import Popen, PIPE
    from flask import Flask

1.8 模块级的魔法函数名

  • 像 __all__,__author__,__version__等模块级的魔法函数,应该放在文档字符串后面,并且在除了
    from future import xxx 语句以外其他的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

二、字符串引号

  • 单引号或者双引号均可以,只需要代码风格保持一致即可
  • 三引号推荐使用三个双引号

三、表达式和语句块中的空格

3.1 不能忍受的

  • 下列情况下不允许使用空格

    • 紧跟在小括号、中括号、大括号后
    • 紧贴在逗号,分号或者冒号之前,注意在切片中的冒号,两边需要有相同数量的空格,当切片参数省略时,空格也必须省略
    • 紧贴在函数参数的左括号之前
    • 紧贴索引或者切片的左括号之前
    • 为了和赋值运算符对齐,在赋值运算符之前加多个空格

      # 推荐做法
      spam(ham[1], {eggs: 2})
      if x == 4: print x, y; x, y = y, x
      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]
      spam(1)
      dct['key'] = lst[index]
      x = 1
      y = 2
      long_variable = 3
      
      # 不推荐做法
      spam( ham[ 1 ], { eggs: 2 } )
      if x == 4 : print x , y ; x , y = y , x
      ham[lower + offset:upper + offset]
      ham[1: 9], ham[1 :9], ham[1:9 :3]
      ham[lower : : upper]
      ham[ : upper]
      spam (1)
      dct ['key'] = lst [index]
      x             = 1
      y             = 2
      long_variable = 3

3.2 其他建议

  • 避免在尾部添加空格
  • 总是在二元运算符两天各添加一个空格
  • 如果使用具有不同优先级的运算符,推荐在具有最低优先级的运算符周围加空格,但是最多使用一个空格,

并且在二元运算符两边使用相同数量的空格

  • 在函数调用或定义中使用默认值或者指定参数的时候,=前后不要使用空格
  • 功能型注释应该使用冒号的一般性原则,并且在使用->的时候前后需要使用空格
  • 当给有类型备注的参数赋值的时候,在=两边添加空格,注意这里仅针对有类型备注说明的
  • 复合语句(一行中有多个语句)通常是不允许的

    # 推荐做法
     i = i + 1
     submitted += 1
     x = x*2 - 1
     hypot2 = x*x + y*y
     c = (a+b) * (a-b)
     def complex(real, imag=0.0):
         return magic(r=real, i=imag)
     def munge(input: AnyStr): ...
     def munge() -> AnyStr: ...
     def munge(sep: AnyStr = None): ...
     def munge(input: AnyStr, sep: AnyStr = None, limit=1000): ...
     if foo == 'blah':
         do_blah_thing()
     do_one()
     do_two()
     do_three()
    
    # 不推荐做法
     i=i+1
     submitted +=1
     x = x * 2 - 1
     hypot2 = x * x + y * y
     c = (a + b) * (a - b)
     def complex(real, imag = 0.0):
         return magic(r = real, i = imag)
     def munge(input:AnyStr): ...
     def munge()->PosInt: ...
     def munge(input: AnyStr=None): ...
     def munge(input: AnyStr, limit = 1000): ...
     if foo == 'blah': do_blah_thing()
     do_one(); do_two(); do_three()

四、注释

4.1 注释说明:

  • 与代码相矛盾的注释比没有注释更糟糕,当代码更改时,优先更新对应的注释
  • 注释应该是完整的句子,如果一个注释是一个短语或句子,它的第一个单词应该大写
  • 注释中永远不要改变标识符的大小写
  • 如果注释很短,结尾的句号可以省略
  • 块注释一般由完整句子的一个或者多个段落组成,并且每句话结束有个句号
  • 在句尾结束的时候应该使用两个空格
  • 在非英语国家的python程序员,请使用英语写注释,除非120%的确定你的代码不会被其他语言的人阅读

4.2 块注释

  • 块注释通常适用于跟随他们的某一些(或全部)代码,并缩进到代码相同的级别
  • 块注释的每一行开头使用一个#和一个空格(除非注释内部缩进文本)
  • 块注释内部的段落通过只有一个#的空行分隔

4.3 行注释

  • 有节制的使用行注释
  • 行注释是与代码同行的注释,行注释和代码之间至少两个空格分隔
  • 行注释由一个#和一个空格开始

4.4 文档注释

  • 要为所有的公共模块、函数、类以及方法编写文档说明,非公共的方法没有必要,但是应该有一个描述方法具体作用的注释,这个注释在def那一行之后
  • 多行文档注释的结尾的三个引号需要独自成一行
  • 对于单行的文档注释,结尾的三个引号应该和文档在一行

五、命名规范

5.1 最重要的原则

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

5.2 命名风格

  • lower_case_with_underscores 使用下划线分割的小写字母
  • CapitalizadWords 驼峰命名法
  • mixedCase 第一个单词的首字母小写
  • lowercase 小写字母
  • UPPERCASE 大写字母
  • UPPER_CASE_WITH_UNDERSCORES 使用下划线分割的大写字母
  • b 单个小写字母
  • B 单个大写字母
  • Capitalized_Words_With_Underscores(巨丑)

5.3 命名约定

5.3.1 应避免的命名

  • 永远不要使用实木'l'(小写的L),‘O’(大写的o)或者I(大写的i)作为单字符变量名

5.3.2 包和模块命名

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

5.3.3 类命名

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

5.3.4 异常命名

  • 异常一般都是类,所以使用类名约定,此外需要在异常名后加上‘Error’后缀

5.3.5 全局变量命名

  • 全局变量名应该小写,如果为了提高可读性,可以使用下划线

5.3.6 函数名命名

  • 函数名应该小写,如果为了提高可读性,可以使用下划线

5.3.7 函数和方法的参数命名

  • 和普通的变量名一致,即小写,如果为了提高可读性,可以使用下划线

5.3.8 方法名和实例变量命名

  • 方法名和函数名一致,可以使用下划线
  • 非公有方法名以单下划线开头
  • 实例变量使用单下划线开头

5.3.9 常量命名

  • 通过下划线分割的全大写字母,如 MAX_OVERFLOW

5.3.10 继承设计

  • 公共属性不应该有前缀下划线
  • 如果不确定一个属性时公有还是非公有,选择非公有,因为非公有转换为公有比

反过来简单的多

  • 对于单一的公有属性数据,最好直接暴露它的变量名
  • 不希望子类使用的属性,使用双下划线开头

5.4 公共和内部接口

  • 为了更好的支持自省,模块应该使用__all__,属性显式的在他们的公共API中声明
  • 即使通过__all__设置过,内部接口(包,模块,类,方法,属性或其他名字)依然需要单个下划线前缀

六、编码建议

  • 代码应该用不损害其他Python实现的方式编写
  • 和像None这样的单例对象进行比较的时候应该使用is 或者is not ,永远不要使用等号运算符
  • 始终使用def表达式,而不是通过赋值语句将lambda表达式绑定到一个变量上
  • 从Exception继承异常,而不是BaseException,直接继承BaseException的异常适用于几乎不用来捕捉的异常
  • 返回的语句保持一致
  • 当代码片段局部使用了某个资源的时候,使用with 表达式来确保这个资源使用完后被清理干净
  • 使用 ”.startswith() 和 ”.endswith() 代替通过字符串切割的方法去检查前缀和后缀
  • 对象类型的比较应该用isinstance()而不是直接比较type
  • 不要用 == 去和True或者False比较
# 推荐:
if foo is not None:
def f(x): return 2*x

# 不推荐:
if not foo is None:
f = lambda x: 2*x
目录
相关文章
|
3月前
|
Python
中文csv文本编码转utf8那些事 - python实现
中文csv文本编码转utf8那些事 - python实现
35 1
|
1月前
|
存储 移动开发 算法
Python怎么将图片转换成base64编码
Python怎么将图片转换成base64编码
27 0
|
2天前
|
存储 编解码 运维
第二章 Python字符串处理和编码不再发愁
第二章 Python字符串处理和编码不再发愁
|
2月前
|
Python
20个改善编码的Python异常处理技巧,让你的代码更高效
异常处理是写好代码的一个重要的方面,虽然许多开发人员都熟悉基本的try-except块,但是有很多更深入的知识可以使异常处理更高效、更可读和更python化。所以本文将介绍关于Python异常的20个可以显著改善编码的Python异常处理技巧,这些技巧可以让你熟练的掌握Python的异常处理。
220 4
|
2月前
|
Python
血常规(自动生成报告)(配套Python工具正在编码中)
血常规(自动生成报告)(配套Python工具正在编码中)
48 0
|
2月前
|
Python
在Python中,序数编码(Ordinal Encoding)
在Python中,序数编码(Ordinal Encoding)
42 6
|
2月前
|
机器学习/深度学习 算法 Python
在Python中,独热编码(One-Hot Encoding)
在Python中,独热编码(One-Hot Encoding)
80 8
|
2月前
|
数据采集 机器学习/深度学习 Python
在Python中进行特征编码
在Python中进行特征编码
38 1
|
3月前
|
Python Java Go
Python每日一练(20230409) 字符串拆分数值求和、快乐数、格雷编码
Python每日一练(20230409) 字符串拆分数值求和、快乐数、格雷编码
40 0
Python每日一练(20230409) 字符串拆分数值求和、快乐数、格雷编码
|
3月前
|
存储 自然语言处理 算法
Tokenization 指南:字节对编码,WordPiece等方法Python代码详解
在2022年11月OpenAI的ChatGPT发布之后,大型语言模型(llm)变得非常受欢迎。从那时起,这些语言模型的使用得到了爆炸式的发展,这在一定程度上得益于HuggingFace的Transformer库和PyTorch等库。
60 3