pep8笔记

Python Enhancement Proposal #8笔记

官网:PEP 8: The Style Guide for Python Code

参考:(90条消息) Python PEP8 编码规范中文版_冒冒大虾的博客-CSDN博客 

1、代码布局

1.1 缩进

        a、每级缩进使用4个空格

        b、不混用空格和制表符。

        如对函数示例

foo = get(var_a,var_b,var_c,var_d)

        通常采用垂直缩进悬挂缩进,如下:

        垂直缩进:首行带参数,下一行参数对其左括号

        悬挂缩进:首行不带参数,下一行参数多一级缩进

# 垂直缩进,对齐括号
foo = get(var_a,var_b,
          var_c,var_d)

# 悬挂缩进,不对齐括号,多加一级缩进,这里是两级,8个空格
foo = get(
        var_a,var_b,
        var_c,var_d)

        注:对于悬挂缩进,可不严格采用缩进4个空格,如下:

foo = get(
 var_a,var_b,
 var_c,var_d)

1.2 跨行的if语句

        当if语句具有and、or情况时,同样有垂直缩进、悬挂缩进两种形式:

        if垂直缩进:and放置首行,第二个条件对齐左括号

if(one_thing and
   two_thing)
    do()

        if悬挂缩进:and放置第二行,加一级缩进

if(one_thing 
        and two_thing)
    do()

1.3 右括号,对所有括号

        a、右括号换行,不回退

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

result = do_some(
    val1,val2
    val3,val4
    )

        b、右括号换行,回退

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


result = do_some(
    val1,val2
    val3,val4
)

1.4 空格和tab规范

        空格是首选的缩进方法。
        Tab仅仅在已经使用tab缩进的代码中为了保持一致性而使用。
        Python 3中不允许混合使用Tab和空格缩进。
        Python 2的包含空格与Tab和空格缩进的应该全部转为空格缩进。
        Python2命令行解释器使用-t选项时有非法混合Tab和空格的情况会告警。当使用-tt警告提升为错误。

2、最大行宽

        在coding时,注意限制代码、注释最多72个字符

        因为多数工具默认的续行功能会破坏代码结构,使它更难理解,不推荐使用。

2.1 续行

        在各种括号中,可以直接按照缩进规范换行,此外,在代码末尾添加反斜线‘\’实现换行。

        如:

with open(path1) as f1, \
     open(path2) as f2:
     do(f1,f2)

2.2 空行

        a、函数和类之间的空行:2行分割
        b、类的方法定义之间空行:单行分割。
        c、必要时,可用额外空行分割不同的函数组----尽量节约使用。
        d、必要时,可用额外空行分割不同的逻辑块-----尽量节约使用。
        e、Python接 contol-L作为空白符;许多工具视它为分页符,这些要因编辑器而异。

 2.3 源文件编码

        核心Python发布代码:应该总是使用UTF-8(ASCII在Python 2)。

        ASCII文件(Python 2)或UTF-8(Python 3)不应有编码声明。

        标准库中非默认的编码应仅用于测试或当注释或文档字符串,比如包含非ASCII字符的作者姓名,尽量使用\x , \u , \U , or \N。

        Python 3.0及以后版本,PEP 3131可供参考,部分内容如下:在Python标准库必须使用ASCII标识符,并尽量只使用英文字母。此外字符串和注释也必须用ASCII。唯一的例外是:

        (a)测试非ASCII的功能,和(b)作者的名字不是拉丁字母。

3、导入包的规范

        导入包的顺序应该符合下列组顺序,且每个组之间空一行

        a、标准库:os、time等

        b、第三方库:pandas、matplotlib、torch 等

        c、自定义.py文件/函数

         导入的库应该处于单独行。

        如:

# 先导入标准库,两个标准库处于单独行
import math
import os

# 再导入需要的第三方库
import matplotlib.pyplot as plt

# 最后导入自定义库
import MyPyFile as my_py

         此外,应注意导入应处于文件的顶部,且使用绝对路径导入

        不推荐使用:通配符导入,如:from A import *,这里会导入A的所有工具,可能会与自定义或其它库存在命名冲突。

4、字符串引用

        在python中,使用单引号、双引号均可,但需要尽量避免在字符串中的反斜杠,以提高可读性

5、表达式、语句中的空格

5.1 强制要求

        a、括号中尽量避免空格,如圆括号首参数前;

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

        b、逗号、冒号、分号之前避免空格;

if x == 4: print x, y:x, y = y, x

        c、索引中冒号前后采用一样的空格数,或无空格

x = a[:-2]
y = b[-5:][get_loc(x)]

        d、函数调用、索引等左括号前不能有空格

func(a)
x['key'] = value1

        e、操作符前后空格数量应一致,推荐前后1空格;

x = 3
b = x == 3

5.2 建议

        a、二元运算符前后加空格,优先级高的运算符前后则不加空格

        涉及 =、符合操作符 ( += , -=等)、比较( == , < , > , != , <> , <= , >= , in , not in , is , is not )、布尔( and , or , not )。

x = a + 1
y = (x*3) + 3

        b、关键字参数、默认参数前后不加空格

def do_some(val1, val2=0.5):  # 默认参数
    return val1 + val2

def do_complex(a, b=20):
    return do_some(val1=a, val2=b)  # 关键字参数

        c、函数注释中,=前后要有空格,冒号和"->"的前面无空格,后面有空格。

def munge(input: AnyStr):
def munge(sep: AnyStr = None):
def munge() -> AnyStr:
def munge(input: AnyStr, sep: AnyStr = None, limit=1000):

           d、避免多行语句写在一行

Yes
if x == 3:
    print(x)

No
if x == 3: print(x)

6、注释

        尽量用英语写注释,修改代码时,优先更新注释。

6.1 注释位置

        a、代码上方,与代码缩进位置相同;

        b、代码右侧,采用两个空格隔开。

# get result
result = do()

a = b + 1  # get the value of a

6.2 文档字符串

        即三个双引号

"""return a
there is a words line
"""

        通常在函数定义def下方增加文档字符串,用于说明该函数的作用,注意,结尾的"""在单独一行

7、版本标签

        源文件中git、subversion、cvs、rcs crud信息,放在文档字符串之后,任何其它代码之前,上下各用一个空行。

__version__ = "$Revision$"# $Source$

8、命名规定

8.1 命名规避字母

        避免使用小写的字母‘eoh’l大写字母‘ai’I大写字母‘oh’O,作为单个变量名或变量名的首字母。

8.2 命名约定规范

        类命名:首字母大写的驼峰命名法,如:class MyCls

        模块命名:小写字母命名,每个单词之间用下划线隔开,增加可读性,如:module_temp

        包命名:小写字母命名,但不用下划线,如:firstpackage

注:模块是一个单独的文件,包含了 Python 的定义、语句和可执行代码(即包含类,函数等)。包是一个包含模块和其他包的文件夹,用于组织和管理相关的模块。

        异常名:在类名后缀‘Error’

        函数名:小写字母命名,单词之间用下划线隔开,如:def my_func():,注,如c++一般的首字母小写的驼峰命名myFunc仅允许用于兼容性考虑。

        全局变量名、方法名、实例变量:小写字母命名单词之间用下划线隔开。

        函数和方法的参数:实例第一个参数为self,类方法第一个参数为cls。当函数参数与关键字冲突,在参数名后加一个下划线,如:param_。

        常量:大写字母加下划线,如:MAX_ART_LIST

        继承设计:

考虑类的方法和实例变量(统称为属性)是否公开。如果有疑问,选择不公开;把其改为公开比把公开属性改为非公开要容易。

公开属性可供所有人使用,并通常向后兼容。非公开属性不给第三方使用、可变甚至被移除。

这里不使用术语"private", Python中没有属性是真正私有的。

另一类属性是子类API(在其他语言中通常称为 “protected”)。 一些类被设计为基类,可以扩展和修改。

谨记这些Python指南:

        a、公开属性应该没有前导下划线。
        b、如果公开属性名和保留关键字冲突,可以添加后置下划线
        c、简单的公开数据属性,最好只公开属性名,没有复杂的访问/修改方法,python的      Property提供了很好的封装方法。

        d.如果不希望子类使用的属性,考虑用两个前置下划线(没有后置下划线)命名。

 8.3 公共和内部接口

        任何向后兼容的保证只适用于公共接口。

        文档化的接口通常是公共的,除非明说明是临时的或为内部接口、其他所有接口默认是内部的。(即,内部接口不开放,只开放一个公共接口

        为了更好地支持内省,模块要在__all__属性列出公共API

        内部接口要有前置下划线

        如果命名空间(包、模块或类)是内部的,里面的接口也是内部的。

        导入名称应视为实现细节。其他模块不能间接访名字,除非在模块的API文档中明确记载,如os.path中或包的__init__暴露了子模块。

9、编程建议

        使用多种python实现,PyPy、Jython、IronPython、Pyrex、Psyco等。

9.1 使用.join(),而不是+=

        CPython中 +=、-= 较快,而在Jython很慢,应该使用.join()。

9.2 is与=

        在None的比较中,使用is 或 is not, 而不用=。

Yes
if a is None:
    do()

No
if a == None:
    do()

9.3 用is not ,而不用not。。is

Yes
if a is not None:

No
if not a is None:

 9.4 使用基于类的异常

        比较排序操作最好是实现所有六个操作,而不是代码中实现比较逻辑。functools.total_ordering()装饰符可以生成缺失的比较方法。

9.5 避免使用lambda匿名函数赋值给标识符

        因为lambda不适用于回调和字符串表示。

# Yes
def f(x): 
    return 2*x

# No
f = lambda x: 2*x

9.6 将异常类继承自Exception,而不是BaseException 

        源于异常,而不是BaseException例外。从BaseException直接继承的例外情况追赶他们几乎总是错误的事情做保留。

        要设计基于层次的异常,捕捉到需要的异常,而不是异常引发的位置。能回答:“出了什么问题?”,而不是仅仅指出“问题发生”(参考:https://www.python.org/dev/peps/pep-3151)

9.7 适当使用异常链

        异常链:指在捕获异常的同时,保留原始异常的信息并将其包装在新的异常中,以便更好地追踪和调试问题。

        作用:提高代码的可读性和可维护性。

        在Python3中"raise X from Y"明确表示更换且保留了原来的traceback。

        替换内部异常(在Python2: “raise X"或"raise X from None”)时,确保相关细节转移到新的异常(如转换KeyError为AttributeError保存属性名,或在新的异常中嵌入原始异常)。

        Python2中用" raise ValueError(‘message’)“代替"raise ValueError, ‘message’”
后者不兼容Python3语法。前者续行方便。

        捕获异常时尽量指明具体异常,而不是空"except:"子句。如:

# Yes
try:
    import platform_specific_module
except ImportError:
    platform_specific_module = None

        空"except:“子句(相当于except Exception)会捕捉SystemExit和KeyboardInterrupt异常,难以用Control-C中断程序,并可掩盖其他问题。如果 你捕捉信号错误之外所有的异常,使用"except Exception”。

        空"except:"子句适用的情况两种情况:

        a, 打印出或记录了traceback,至少让用户将知道已发生错误。

        b, 代码需要做一些清理工作,并用 raise转发了异常。这样try…finally可以捕捉到它。

        绑定异常名:python2.6之后支持

try:
    do()
except Exception as exc:
    raise DataProcessingFailedError(str(exc))

        操作系统错误时,建议使用Python 3.3引入显式异常层次,支持内省errno值。

        所有try/except子句的代码要尽可的少,以免屏蔽其他的错误

# Yes
try:
    value = collection[key]
except KeyError:
    return key_not_found(key)
else:
    return handle_value(value)

# No
try:
    # 太泛了!
    return handle_value(collection[key])
except KeyError:
    # 会捕捉到handle_value()中的KeyError
    return key_not_found(key)

9.8 本地资源使用with语句

        对本地资源使用with语句可以确保及时清理,但try/finally也是可用的。 

9.9 上下文管理器在做获取和释放资源之外的事情时,应通过独立的函数或方法。

# Yes
with conn.begin_transaction():
    do_stuff_in_transaction(conn)

# No
with conn:
    do_stuff_in_transaction(conn)

9.10 函数或方法在没有返回时要明确返回None

Yes
def func(a):
    if a > 10:
        return a
    else:   
        return None

No
def func(a):
    if a > 10:
        return a

9.11 检查字符串前缀和后缀时,使用.startswith()和.endswith(),而不使用字符串切片

str = 'bar is bar'

Yes
if str.startswith('bar'):

No
if str[:3] == 'bar':

9.12 用isinstance()进行对象类型比较

Yes
if isinstance(obj,int):

No
if type(obj) is int:

        此外,对于对于序列对象(字符串,列表,元组),空序列为false

seq = []
if seq:  # 这里为False
    pass
if not seq:
    pass

9.13 布尔比较

        使用is ,不用 == 

if bool1 is True:
    do()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值