初入python怎么能不知道PEP-8呢?

pep-8

也算是用了一段时间的python了,但是想要符合python的代码规范pep-8那可是必须读的。

Indentation

缩进是python的一大特点,对于每一个段落(level)的缩进,pep-8给出的规范是4 spaces。有的编辑器默认是8 spaces的,建议修改一下。

对于那些个hanging indents应该视为一个level添加缩进。你可以这样:

#python的缩进可以让代码更readable
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)

但是要避免下面的写法:

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

def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

对于} ] )这样的闭合符号如果跨过了多行怎么办?

你可以对齐元素的level:

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

result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
    )

也可以对齐该结构的level:

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

Tabs or Spaces?

pep-8是这么说的:

Spaces 是首选的缩进方法,Tabs只应该被用在保持用Tabs缩进的段落之间一致性上。
不管是那个,不要混合使用!

Maximum Line Length

一行最多能摆多少字符,嗯...应该是79个。如果是文档注释一类的限制则为72个字符。

你可以用\来在下一行延续你的代码,当然更欢迎使用括号来包裹你的表达式进行换行。

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())

当然在换行过后要确保适当的缩进。

Should a line break before or after a binary operator?

在操作符前换行或者在操作符后面换行。python的特点是readable,所以建议这样写:

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

当然也不是不可以在操作符后面换行,但是要注意保持一致性。

Blank Lines

空白行怎么用?

  • top-level function和class之间两空两行。
  • 类内的方法的定义之间空一行。
  • 在方法中使用空白行作为逻辑区分
  • 其他地方尽量不要再空行。

Source File Encoding

  • 尽量使用UTF-8(或者 ASCII in python2)。
  • 对于使用ASCII码的python2文件或者使用UTF-8的python3文件,不要进行编码声明。
  • 所有的标准库里的标识符都必须使用ASCII编码,并且在可以使用英文的时候尽量使用英文。唯一的一些例外是测试用例和你的名字。开源的项目更鼓励这样做(嗯,应该在来个中文版...)。
  • 不是默认的编码只能用在测试或者注释里。

Imports

imports应该分行写,from something import ...例外:

Yes: import os
     import sys
  
No:  import sys, os

imports应该放在文件的顶部,在模块注释和文档字符串后面,在全局变量和常量之前。

imports还应该按照如下顺序分组:

  • 标准库的imports
  • 第三方部分的imports
  • 本地声明的imports
  • 在每一类imports之间你应该空一行。

把任何有关all的说明放到imports的后面。

Absolute imports or Explicit imports

推荐完全引入,它们更可读也更可靠。

import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example

不过,相对引入也可用于替代绝对完全引入特别是处理复杂的包时完全引入会造成不必要的冗长。

from .import sibling
from .sibling import example

对于标准库的imports必须使用完全引入。要避免from <module> import *这样的写法,这样会带来混淆,对于包的名称要明确并且做好区分,方便管理。

Whitespace in Expressions and Statements

表达式和语句中的空格怎么用?

下面的情况应该避免多余的空格:

  • 紧挨着各种括号应该这么写:Yes: spam(ham[1], {eggs: 2})
  • 后面紧跟着逗号、分号或者冒号:Yes: if x == 4: print x, y; x, y = y, x
  • 紧挨着调用函数括号:Yes: spam(1)
  • 序列的左括号后不要加空格:Yes: dct['key'] = lst[index]
  • 在任何行尾不要使用空格。

其他空格:

  • 在这些个操作符的两边都使用一个空格:assignment (=), augmented assignment (+=,-=etc.), comparisons (==,<,>,!=,<>,<=,>=,in,not in,is,is not), Booleans (and,or,not).
  • 在不同优先级的操作符之间可以考虑添加空格(建议实在优先级低的一边),二元操作符两边使用相同的空格数,不要超过一个
  • 切片里的冒号感觉像一个二元操作符,它的两边应该留有相同个数的空格,如果切片中有扩展冒号,使用相同的格式。当然如果冒号的参数被省略,那么空格也省略:
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
  • 操作符左右各加一个空格使它们对齐(但是不要强行对齐):
x = 1
y = 2
long_variable = 3
  • 在函数定义中的参数默认值和key值所使用的=号两边不要添加空格:def complex(real, imag=0.0):
  • 不鼓励使用组合语句,也就是尽量不用 ; 组合,该分行的时候就分行。
  • if / for / while语句块中,该分行就分行,即使只有一行。

Comments

哈哈,这个跟hello world基本上出现频率相同的东西又来啦——注释。

  • 误导人的注释有了不如没有,所以记得更新你的注释。
  • 在你的注释里不要改变表示符的写法,make it readable。并且要让你的注释是一个大写开头 句号结尾 的完整的句子。
  • 在每个句子结束的时候应该用两个空格。
  • 中国的朋友请用英语编写注释,除非你120%的肯定不会有老外看...

Python coders from non-English speaking countries: please write your comments in English, unless you are 120% sure that the code will never be read by people who don't speak your language.

其实我想说:
Python coders from English speaking countries: please write your comments in Chinese, unless you are 120% sure that the code will never be read by people who just speak Chinese.
好吧纯属玩笑啦。

Block Comments:块注释,用于注释跟着它的那些个代码,注释应该和备注释的代码处于同一个level,使用一个#和一个空格开始,如果要分段的话,使用只有#的空白行注释分割。
Inline Comments:行注释,再需要的时候使用,做一些适当的说明。使用一个#和一个空格。
Documentation Strings:文档字符串,你应该为每一个公共的模块,函数,类,方法写一个文档字符串,非public的函数也许不需要文档字符,但是你应该在它的def之后给他写一个注释。在变写文档字符的时候也要保持"""的缩进。

Version Bookkeeping

版本声明,在你的source file里面添加:__version__ = "$Revision: 9afe77ad549b $"这行代码应该紧跟在文档字符串后面。

Naming Conventions

命名规范。先来一看一看:

The naming conventions of Python's library are a bit of a mess, so we'll never get this completely consistent -- nevertheless, here are the currently recommended naming standards. New modules and packages (including third party frameworks) should be written to these standards, but where an existing library has a different style, internal consistency is preferred.

一般有这么几种命名格式:

  • b(single lowercase letter)
  • B(single uppercase letter)
  • lowercase
  • lower_case_with_underscores
  • UPPERCASE
  • UPPER_CASE_WITH_UNDERSCORES
  • CapitalizedWords(or CapWords, or CamelCase )
    Note: When using abbreviations in CapWords, capitalize all theletters of the abbreviation. Thus HTTPServerError is better thanHttpServerError.
  • mixedCase
    (differs from CapitalizedWords by initial lowercasecharacter!)
  • Capitalized_Words_With_Underscores (ugly!)

python变量中的公认的下划线使用方法:

  • _single_leading_underscore 弱“内部使用”指标。用from module import *的方式不能导入这样的对象。
  • single_trailing_underscore_ 通过_后缀避免与Python关键字的冲突,例如Tkinter.Toplevel(master, class_='ClassName')
  • __double_leading_underscore 当命名类属性的时候,使得(类foobar内的__boo成为_foobar__boo;这是python的名称修改机制见下文)
  • __double_leading_and_trailing_underscore__ “奇妙”的对象或者属性,不要发明这样的名字,用文档里面定义好的。
  • 在python中很少使用统一前缀来表示有相近关系的变量

命名规定:

  • Names to Avoid:不要单独使用l O I这几个字母作为变量名。
  • Package and Module Names:模块命名尽量短小,使用全部小写的方式,可以使用下划线。包命名尽量短小,使用全部小写的方式,不可以使用下划线。C/C++的扩展用到python的话命名使用_modulename的方式。
  • Class Names:类的命名使用ClassName的方式,模块内部使用的类采用_ClassName的方式。
  • Exception Names:异常命名使用CapWords+Error后缀的方式。
  • Function Names:函数命名使用全部小写的方式,可以使用下划线。
  • Global Variable Names:全局变量命名使用函数的命名方式。实现单模板的全局变量方法有两种,一是在其他模板导入时使用all机制;二是前缀一个下划线(即将变量视为模板非公开)。
  • Function and method arguments:函数和方法的变量名称的命名,self,cls分别对应实例方法和类方法的第一个参数 。如果参数与关键字重名,在最后加一个下划线。
  • Constants:常量通常定义在模块层,常量命名使用全部大写的方式,可以使用下划线。
  • Method Names and Instance Variables:方法名称和实例变量的命名规则和函数的命名规则一致。还应注意:
    • 如果是非公的方法或者实体在命名前面加上一个下划线。
    • 为了避免子类父类命名冲突,用两个前缀下划线调用python的名称改写机制。
    • 这里是原文的引用:

Use one leading underscore only for non-public methods and instance variables.
To avoid name clashes with subclasses, use two leading underscores to invoke Python's name mangling rules.
Python mangles these names with the class name: if class Foo has an attribute named __a, it cannot be accessed by Foo.__a. (An insistent user could still gain access by calling Foo._Foo__a.) Generally, double leading underscores should be used only to avoid name conflicts with attributes in classes designed to be subclassed.

Designing for inheritance

提供面向对象的语言都涉及继承的设计,python也不例外。

在设计之初一定要决定类的方法和实例变量应该是公有的还是非公的,如果还没有决定,那就先设为非公的,因为从非公到公的转化比从公到非公的转化简单,改得时候方便。

python里省略了private,python中没有真正意义上的private变量,这样使事情变得轻松不少。

还有一种属性是作为“子类的API”存在的(其他语言称为protect的属性)。有些类生来就是要被继承的,在子类中做些扩展改变一下类的方法行为,在设计这样的类的时候,明确的决定好哪些属性是公有的,哪些是作为子类的API的,哪些是只用与基类的。

With this in mind, here are the Pythonic guidelines:

  • 公有的属性名不要有前缀下划线
  • 如果你的共有的属性名字与保留的关键字冲突,最好缩写一下。 (However, notwithstanding this rule, 'cls' is the preferred spelling for any variable or argument which is known to be a class, especially the first argument to a class method.)
  • 对于简单的数据属性,简单明了的命名就好。
  • 如果你的类要派生子类,并且你有不想让子类访问的类型,考虑将它们使用双下划线前缀并且没有后缀下划线的方式命名,这会调用python的名称改写算法。这可以帮助你避免子类不小心出现和父类同名属性而产生的问题。
    • 只有单继承有这样的机制,如果一个子类选择了同名的class和同名的属性名,还是会有冲突。
    • 名称改写机制会让一些工作变得不是很方便,比如调试和__getarr()__,然而记录和易于手动执行。
    • 不是每个人都喜欢名称改写。

Public and internal interfaces

公共和内部接口。

模块应该用一个__all__显示的声明它的公开接口,文档化的接口如果在文档内部没有说明那么它应该是一个公共接口。

内部的接口在名字前面加上_

__author__=='xuehao'

在下初入python,如果内容有差错,还请大家指出。
email:darkframexue@outlook.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容

  • 更新时间:2016/5/13 介绍 本文档所提供的编码规范,适用于主要的Python发行版中组成标准库的Pytho...
    超net阅读 5,840评论 0 15
  • --< > 令人讨厌的小人物身上有着愚蠢的一致性 --(A Foolish Consistency is the ...
    LittleWizard阅读 3,191评论 0 4
  • PEP介绍 PEP是 Python Enhancement Proposal 的缩写,是Python增强建议书的意...
    JasonDing阅读 4,786评论 3 40
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,561评论 18 139
  • Python编码规范 1 排版 1.1 Indentation缩进 在参数过多时适当缩进 换行应该使用同级的缩进...
    帝Bug阅读 821评论 0 1