python编码规范

本文介绍了Python代码规范及编程建议。规范涵盖源文件编码、缩进、行长度等方面,还提及命名规范和继承设计。编程建议包括字符拼接、与None比较、使用运算符等,如推荐用join拼接字符,用is或is not与None比较等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码规范好处

1、提高代码的可读性
    可直接选用python的PEP8官方风格指南,严格遵守可得到美观、统一风格的项目代码
 
2、可帮助发现影藏的bug
    比如未定义的变量,定义了变量却没使用,变量覆盖等等   
 
3、可稍微提高性能
    比如定义的变量未使用,引入的模块未使用等,会造成额外的性能消耗和代码冗余,代码规范可以方便地检查出来
 

源文件编码:

无特殊情况,文件一律使用utf-8编码,文件头部加入 # -*- coding: utf-8 -*-

 

 
 

缩进:

每一级缩进使用4个空格
续行应该与其包裹元素对齐,要么使用圆括号、方括号和花括号内的隐式行连接来垂直对齐,要么使用挂行缩进对齐3。当使用挂行缩进时,应该考虑到第一行不应该有参数,以及使用缩进以区分自己是续行

 

 
 
 

行长度:

每行不超过80个字符,以下除外:
    1、长的导入模块语句
    2、注释里的url   没有结构化限制的大块文本(文档字符或者注释),每行的最大字符数限制在72

较长的代码行选择Python在小括号,中括号以及大括号中的隐式续行方式。通过小括号内表达式的换行方式将长串折成多行。这种方式应该优先使用,而不是使用反斜杠续行。

反斜杠有时依然很有用。比如,比较长的,多个with状态语句,不能使用隐式续行,所以反斜杠是可以接受的:
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)

# 推荐:在二元运算符之前中断,运算符和操作数很容易进行匹配
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

 

 
 
 

空行:

模块级函数和类定义之间空两行,类成员之间空一行;可以使用多个空行分隔多组相关的函数,函数中可以使用空行分隔出逻辑相关的代码
   
 
 
 

imports导入:

你不应该使用老式的相对导入:
from module import foo         # BAD!
from proj.module import foo  # GOOD!
 
新式的相对导入能够被正常使用:
from .module import foo      # GOOD!
 
 
千万不要from module import *(这样做会不知道命名空间中存在哪些名字,会使读取接口和许多自动化工具之间产生混淆 ),建议用哪个导入哪个: from subprocess import Popen, PIPE
 
不要一句import多个库:
推荐: import os
      import sys

不推荐:  import sys, os

 

 
 
 

模块的编排:

导入总是位于文件的顶部,在模块注释和文档字符串之后,在模块的全局变量与常量之前;
推荐使用绝对路径导入
 
按照标准、第三方、自己编写的顺序依次排序,之间空一行
 
 
 
 
 
 
 

字符串引号:

Python中,单引号和双引号字符串是相同。
当一个字符串中包含单引号或者双引号字符的时候,使用和最外层不同的符号来避免使用反斜杠,从而提高可读性。
a = "a d f \"s\""
a = "a d f 's'"
 
 
 
 

表达式和语句中的空格:

在下列情况下,避免使用无关的空格:
    1、紧跟在小括号、中括号、大括号后:
Yes: spam(ham[1], {eggs: 2})
No:  spam( ham[ 1 ], { eggs: 2 } )

     2、紧贴在逗号、分号或者冒号之前:
Yes: if x == 4: print x, y; x, y = y, x
No:  if x == 4 : print x , y ; x , y = y , x

     3、紧贴在函数参数的左括号之前:
Yes: spam(1)
No:  spam (1)

    4、紧贴索引或者切片的左括号之前:
Yes: dct['key'] = lst[index]
No:  dct ['key'] = lst [index]

    5、为了和另一个赋值语句对齐,在赋值运算符左侧加多个空格。:
Yes: 
    x = 1
    y = 2
    long_variable = 3
No:  
    x             = 1
    y             = 2
    long_variable = 3

 

 
 
 
 
 
 

 

块注释、行注释、文档注释:

顶级定义之间空两行, 比如函数或者类定义. 方法定义, 类定义与第一个方法之间, 都应该空一行
 
 
注释一定要与代码相匹配,错误的注释不如没有注释。请使用英文写注释。
注释应该是完整的句子。如果一个注释是一个短语或句子,它的 第一个单词应该大写,除非它是以小写字母开头的标识符(永远不要改变标识符的大小写!)。
 
 
块注释:
每行以#开头,“#”号后空一格
注释使用英文,错误的注释不如没有注释
注释应包括:功能、入参、出参
 
 
 
行注释:
至少使用两个空格和代码语句分 ,注释由#和一个空格开始 ,注意不要使用无意义的注释
错误的写法:
 
正确的写法:
 
 
 
 
在代码的关键部分,能写注释的尽量写注释;比较重要的注释段,使用多个等号隔开
 
 
 
文档注释:
公共模块、公有类、公有方法,应该尽量写文档注释。非公共的方法没有必要,但是应该有一个描述方法具体作用的注释。 这个注释应该在def那一行之后。
特别需要注意的是, 多行文档说明使用的结尾三引号应该自成一行
 
参考如下格式:
def func(arg1, arg2):
    """函数实现的功能.
 
    参数
    ----------
    arg1 : int
        arg1的描述.
 
    arg2 : int
        arg2的描述
 
    返回值
    ------
    result :int
        返回值的描述
    """
 
 
对于单行的文档说明,尾部的三引号应该和文档在同一行。
 
 
 

 

命名规范

python库的命名规范比较混乱,没有做到完全一致,至少保证一个库内的风格一致。
 
1、模块命名短小,使用全部小写,可使用下划线
      
2、包命名短小,使用全部小写,不可以使用下划线
   
3、函数命名使用全部小写,可使用下划线
      
4、变量名尽量小写,多个单词间用下划线隔开
5、全局变量名 希望这一类变量只在模块内部使用,小写、可以使用下划线。    全局变量前加上下划线表名该变量是模块内非公有
5、常量命名使用全部大写,可使用下划线,通常定义在模块级
      
6、类名  使用驼峰(CamelCase)命名风格,首字母大写,私有类可用一个下划线开头
 
 
7、异常名 因为异常一般都是类,所有类的命名方法也是用,但你需要在异常名后加上“Error”后缀(如果异常却是个错误)
 
 
 
 
 
 
 

继承的设计:

考虑一个类的方法与实例变量应该是共有还是非共有, 如果存在疑问,那就选非共有,因为将一个非共有变量转为共有比反过来更容易。
 
公共属性是那些与类无关的客户使用的属性,并承诺避免向后不兼容的更改, 不许改
非共有属性是那些不打算让第三方使用的属性,你不需要承诺非共有属性不会被修改或被删除, 允许改
 
准则:
  • 公共属性不应该由前缀下划线
  • 如果公共属性名与关键字冲突,在属性名之后加一个下划线。
  • 若你的类打算用来继承的话,并且这个类里有不希望子类使用的属性,就要考虑使用双下划线前缀并且没有后缀下划线的命名方式。
 

 

编程建议:

  • 字符拼接,考虑性能,不推荐"a" + "b",推荐"".join(["a","b"])
  • 与None对象比较,建议用is 或者 is not,不要用等号运算符
  • 使用 is not 运算符,而不是 not … is,虽然这两种表达式在功能上完全相同,但前者更易于阅读,所以优先考虑, 推荐if foo is not None:,不推荐if not foo is None:
  • 始终使用def表达式,而不是通过赋值语句将lambda表达式绑定到一个变量上
推荐:
def f(x): 
    return 2*x
 
不推荐:
f = lambda x: 2*x
  • 当代码片段局部使用了某个资源的时候, 使用with 表达式来确保这个资源使用完后被清理干净。用try/finally也可以
  • 返回的语句保持一致。函数中的返回语句都应该返回一个表达式,或者都不返回。如果一个返回语句需要返回一个表达式,那么在没有值可以返回的情况下,需要用 return None 显式指明,并且在函数的最后显式指定一条返回语句(如果能跑到那的话)
推荐:
def foo(x):
    if x >= 0:
        return math.sqrt(x)
    else:
        return None
 
 
def bar(x):
    if x < 0:
        return None
    return math.sqrt(x)
 
不推荐:
def foo(x):
    if x >= 0:
        return math.sqrt(x)
 
 
def bar(x):
    if x < 0:
        return
    return math.sqrt(x)
  • 使用字符串方法代替字符串模块。 字符串方法总是更快,并且和unicode字符串分享相同的API。如果需要兼容Python2.0之前的版本可以不用考虑这个规则。
  • 使用 ”.startswith() 和 ”.endswith() 代替通过字符串切割的方法去检查前缀和后缀,startswith()和endswith()更干净,出错几率更小
推荐: if foo.startswith('bar'): 
糟糕: if foo[:3] == 'bar':
  • 对象类型的比较应该用isinstance()而不是直接比较type
正确: if isinstance(obj, int): 
糟糕: if type(obj) is type(1):
  • 对于序列来说(strings,lists,tuples),可以使用空序列为false的情况
正确: if not seq:
      if seq:
 
 
糟糕: if len(seq):
      if not len(seq):
  • 不要用 == 去和True或者False比较:
正确: if greeting:
糟糕: if greeting == True:
更糟: if greeting is True:
 
 
 
 
 
 
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值