Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Einführung in das Python-Codierungsformat (mit Beispielen)

Detaillierte Einführung in das Python-Codierungsformat (mit Beispielen)

不言
不言nach vorne
2019-01-28 10:56:453607Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Einführung in das Python-Codierungsformat (mit Beispielen). Freunde in Not können darauf verweisen.

Neben dem Ausführen wird der Code auch zum Lesen verwendet. Um den Code besser lesbar zu machen, haben viele Programmiersprachen eigene Codierungsstandards. Spezifikationen werden entwickelt, um die Codekonsistenz aufrechtzuerhalten und den Code schöner und lesbarer zu machen. Wie Code formatiert und geschrieben werden sollte, ist nicht absolut, daher werden einige Bereiche umstritten sein. Manchmal gelten Styleguides nicht, und das Wichtigste ist, zu wissen, wann man inkonsistent sein muss. Wenn Sie sich nicht sicher sind, was Sie tun sollen, sollten Sie sich andere Beispiele ansehen.

Dieser Artikel ist nur eine Referenz für den Python-Codierungsstil, keine Regel, die vorschreibt, dass dies getan werden muss. Der Zweck dieses Artikels sollte darin bestehen, Entwicklern als Leitfaden zu dienen, damit sie besser lesbaren Code schreiben können.

1. Code-Layout

Hauptsächlich das Layout von Einrückungen und Leerzeilen:

  • 1 (Jeder Editor kann diese Funktion ausführen), Tabulatoren werden nicht empfohlen und Tabulatoren und Leerzeichen können nicht gemischt werden.

  • 2. Jede Zeile sollte 80 Zeichen nicht überschreiten. Für Zeilenumbrüche können Sie am besten Klammern verwenden (Python wird implizit verbunden).

  • Zwei Leerzeilen zwischen Klassen- und Top-Level-Funktionsdefinitionen; eine Leerzeile zwischen logisch irrelevanten Absätzen innerhalb von Funktionen; an anderen Stellen Leerzeile.

Hauptsächlich das Layout der gesamten Quellcodedatei:

  • 1. Die Reihenfolge des Modulinhalts: Modulbeschreibung, Moduldokumentation Zeichenfolge, Importanweisungen, globale Variablen oder Konstanten, andere Definitionen.

  • 2. Die Reihenfolge der Modulimportteile: Standardbibliothek, Drittanbietermodul, benutzerdefiniertes Modul. Zwischen jedem Teil befindet sich eine Leerzeile.

  • 3. Importieren Sie nicht mehrere Module gleichzeitig in einer Importanweisung, da import os, sys nicht empfohlen wird.

  • 4. Beim Importieren von Modulen sollten Sie geeignete Methoden verwenden, um Namenskonflikte zu vermeiden. Verwenden Sie beispielsweise from xx import xx nur, wenn dies angemessen ist, und vermeiden Sie die Verwendung von from xx imoprt *.

  • 5. Wenn Sie in einem selbst geschriebenen Modul from xx import * verwenden müssen, sollten Sie den __all__-Mechanismus nach der Importanweisung oder am Ende des Moduls verwenden Beschränken Sie die Importregeln.

3. Anweisungsanordnung

  • 1. Normalerweise sollte jede Anweisung in einer eigenen Zeile stehen.

  • 2. Fügen Sie am Ende der Zeile kein Semikolon hinzu und verwenden Sie keine Semikolons, um mehrere Anweisungen in derselben Zeile zu platzieren.

  • 3. Versuchen Sie, in der if/for/while-Anweisung eine neue Zeile zu beginnen, auch wenn es nur eine Ausführungsanweisung gibt.

  • 4. Verwenden Sie keine Klammern in Rückgabeanweisungen (return) oder bedingten Anweisungen (if/for/while), es sei denn, sie werden zum Verbinden von Zeilen verwendet.

  • 5. Wenn keine andere Aussage vorhanden ist und die Aussage relativ kurz ist, kann sie in einer Zeile vervollständigt werden (aber nicht empfohlen), wie zum Beispiel: if foo: bar(foo).

  • 6. Für eine einfache Klassendefinition kann es auch in einer Zeile ausgefüllt werden (aber nicht empfohlen), z. B. die Definition einer Ausnahme: class UnfoundError(Exception): pass.

  • 7. Funktionen und Methoden Verwenden Sie den vertikalen impliziten Einzug in Klammern oder den hängenden Einzug.

# 一行写不下时,有括号来连接多行,后续行应该使用悬挂缩进
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

# 函数调用参数较多时,对准左括号
f = foo(a, b,
        c, d)

# 不对准左括号,但加多一层缩进,以和后面内容区别
def long_function_name(
        a, b, c,
        d, e):
    print(a, b, c, d, e)

# 列表、元组、字典以及函数调用时可以让右括号回退,这样更加美观
l = [
    1, 2, 3,
    4, 5, 6,
]

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

4. Verwenden Sie das allgemeine Prinzip von

für Leerzeichen, um unnötige Leerzeichen zu vermeiden.

  • 1. Fügen Sie vor verschiedenen schließenden Klammern keine Leerzeichen ein.

  • 2. Fügen Sie keine Leerzeichen vor Kommas, Doppelpunkten und Semikolons ein, sondern sie sollten danach eingefügt werden (außer am Ende der Zeile).

  • 3. Fügen Sie vor der linken Klammer der Funktion kein Leerzeichen ein. Wie zum Beispiel Func(1).

  • 4. Fügen Sie vor der linken Klammer der Sequenz kein Leerzeichen ein. Wie zum Beispiel list[2].

  • 5. Fügen Sie links und rechts vom Operator ein Leerzeichen hinzu.

  • 6. Lassen Sie Leerzeichen um die Zuweisungszeichen weg, die von den Standardparametern der Funktion verwendet werden.

Guter Stil:

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

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

f = foo(1, 2, 3)

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]

x = 1
y = 2
long_variable = 3

def foo(a, b, c=0):
    return moo(m=a, n=b, o=c)

Schlechter Stil:

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

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

f = foo (1, 2, 3)

ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]

x             = 1
y             = 2
long_variable = 3

def foo(a, b, c = 0):
    return moo(m = a, n = b, o = c)

5. Kommentare

Allgemeine Grundsätze, falsche Kommentare Es ist besser zu haben keine Kommentare. Wenn sich also ein Teil des Codes ändert, müssen zunächst die Kommentare geändert werden. Kommentare sollten so weit wie möglich auf Englisch verfasst sein, vorzugsweise vollständige Sätze, wobei der erste Buchstabe groß geschrieben werden sollte. Nach dem Satz sollte ein Abschlusszeichen stehen, und auf das Abschlusszeichen sollten zwei Leerzeichen folgen, um den nächsten Satz zu beginnen. Handelt es sich um eine Phrase, kann der Terminator weggelassen werden. Kommentare sollten mit einem Leerzeichen nach # beginnen.

  • 1. Kommentar blockieren, ein Kommentar, der vor einem Codeabschnitt hinzugefügt wird. Verwenden Sie Zeilen mit nur „#“ zwischen den Absätzen. Zum Beispiel:

# Description : Module config.
#
# Input : None
#
# Output : None
  • 2. Zeilenkommentare, Kommentare nach einer Codezeile hinzufügen. Sie sollten versuchen, nach der Anweisung zwei Leerzeichen zu lassen, bevor Sie mit dem Kommentar beginnen. Bei fortlaufenden Zeilenkommentaren kann das „#“ der besseren Darstellung halber ausgerichtet werden. Bei langen Anweisungen sollten möglichst wenige Zeilenkommentare verwendet werden. Zum Beispiel:

person = {
    "name": "huoty",  # 姓名
    "age": 26,        # 年龄
    "stature": 169,   # 身高
    "weight": 60,     # 体重
}

print person  # 输出信息
  • 3、对类或者函数的说明,尽量不要在其定义的前一行或者后一行用块注释的形式来说明,而应该使用文档字符串(docstring)

  • 4、使用 TODO 注释来标记待完成的工作,团队协作中,必要的时候应该写上你的名字或者联系方式,比如:

# TODO(sudohuoty@gmail.com): Use a "*" here for string repetition.
# TODO(Huoty) Change this to use relations.
  • 5、避免无谓的注释。你见过哪些奇趣的代码注释?

# 你可能会认为你读得懂以下的代码。但是你不会懂的,相信我吧。  

# 要是你尝试玩弄这段代码的话,你将会在无尽的通宵中不断地咒骂自己为什么会认为自己聪明到可以优化这段代码。  
# so,现在请关闭这个文件去玩点别的吧。  

# 程序员1(于2010年6月7日):在这个坑临时加入一些调料  
# 程序员2(于2011年5月22日):临你个屁啊  
# 程序员3(于2012年7月23日):楼上都是狗屎,鉴定完毕  
# 程序员4(于2013年8月2日):fuck 楼上,三年了,这坑还在!!!  
# 程序员5(于2014年8月21日):哈哈哈,这坑居然坑了这么多人,幸好我也不用填了,系统终止运行了,you're died

六、文档描述

  • 1、尽量为所有的共有模块、函数、类、方法写 docstring

  • 2、前三引号后不应该换行,应该紧接着在后面概括性的说明模块、函数、类、方法的作用,然后再空一行进行详细的说明。后三引号应该单独占一行。比如:

"""Convert an API path to a filesystem path

If given, root will be prepended to the path.
root must be a filesystem path already.
"""
  • 2、函数和方法的 docstring 层次顺序大致为概述、详细描述、参数、返回值、异常,一般不要求描述实现细节,除非其中涉及非常复杂的算法。大致的层次结构如下所示:

"""函数或方法的概述

详细的描述信息……
详细的描述信息……

参数说明
--------
    参数1:...
    参数2:...

返回值:
    ...

异常:
    异常1:...
    异常2:...
"""

一个参考示例:

"""Start a kernel for a session and return its kernel_id.                                                                                             

Parameters
----------
kernel_id : uuid
    The uuid to associate the new kernel with. If this
    is not None, this kernel will be persistent whenever it is
    requested.
path : API path
    The API path (unicode, '/' delimited) for the cwd.
    Will be transformed to an OS path relative to root_dir.
kernel_name : str
    The name identifying which kernel spec to launch. This is ignored if
    an existing kernel is returned, but it may be checked in the future.

Return a kernel id
"""
  • 3、类的 docstring 的层次顺序大致为概述、详细描述、属性说明。如果类有公开属性值时,应该尽量在 docstring 中进行说明。如下所示:

"""这里是类的概述。

详细的描述信息……
详细的描述信息……

属性(Attributes):
-----------------
    属性1: ...
    属性2: ...
"""

七、命名规范

  • 1、模块命名尽量短小,使用全部小写的方式,可以使用下划线。

  • 2、包命名尽量短小,使用全部小写的方式,不可以使用下划线。

  • 3、类的命名使用驼峰命令的方式,即单词首字符大写,类名应该全部使用名词。

  • 4、异常命令应该使用加 Error 后缀的方式,比如:HTTPError。

  • 5、全局变量尽量只在模块内有效,并且应该尽量避免使用全局变量。

  • 6、函数命名使用全部小写的方式,使用下划线分割单词,并采用动宾结构。

  • 7、常量命名使用全部大写的方式,使用下划线分割单词。

  • 8、类的属性(方法和变量)命名使用全部小写的方式,使用下划线分割单词。

  • 9、变量、类属性等命令尽量不要使用缩写形式,除了计数器和迭代器,尽量不要使用单字符名称。

  • 10、类的方法第一个参数必须是 self,而静态方法第一个参数必须是 cls。

  • 11、在模块中要表示私有变量或者函数时,可以在变量或者函数前加一个下划线 _foo, _show_msg 来进行访问控制。

  • 12、在 Python 中没有诸如 public、private、protected 等修饰符,而在类的定义中往往会有类似这样的需求,那么可以在属性或者方法前加一个下划线表示 protected,加两个下划线来表示 private。加两个下划线的变量或者方法没法直接访问。比如:类 Foo 中声明 __a, 则不能用 Foo.__a 的方式访问,但可以用 Foo._Foo__a 的方式访问。`

八、程序入口

Python 属于脚本语言,代码的运行是通过解释器对代码文件进行逐行解释执行来完成的。它不像其他编程语言那样有统一的入口程序,比如 Java 有 Main 方法,C/C++ 有 main 方法。Python 的代码文件除了可以被直接执行外,还可以作为模块被其他文件导入。所有的顶级代码在模块导入时都会被执行,当希望模块被导入时,应该避免主程序被执行。这样就需要把主程序放到 if __name__ == '__main__' 代码块中,比如:

def main():
      ...

if __name__ == '__main__':
    main()

一个包除了能够被导入外,也可以通过 python -m package 的方式被直接执行,前提是包中需要有 __main__.py,这个文件可以说是包的程序入口,包中有了这个文件就可以用 Python 的 -m 参数来直接运行。

九、编码建议

  • 1、尽可能使用 'is' 和 'is not' 取代 '==',比如 if x is not None 要优于 if x != None,另外用 if x 效率更高。

Note: 等于比较运算符(==) 会调用左操作数的 __eq__ 函数,这个函数可以被其任意定义,而 is 操作只是做 id 比较,并不会被自定义。同时也可以发现 is 函数是要快于等于运算符的,因为不用查找和运行函数。

  • 2、用 "is not" 代替 "not ... is",前者的可读性更好。

  • 3、使用基于类的异常,每个模块或包都有自己的异常类,此异常类继承自 Exception。

  • 4、异常中尽量不要使用裸露的 except,except 后应该跟具体的 exceptions。

  • 5、使用 startswith() 和 endswith() 代替切片进行序列前缀或后缀的检查。

  • 6、使用 isinstance() 比较对象的类型,而不是 type(),比如:

# Yes:  
if isinstance(obj, int)

# No:  
if type(obj) is type(1)
  • 7、判断序列是否为空时,不用使用 len() 函数,序列为空时其 bool 值为 False,比如:

# Yes:  
if not seq
if seq

# No:  
if len(seq)
if not len(seq)
  • 8、字符串后面不要有大量拖尾空格。

  • 9、使用 join 合并的字符串,字符串方法 join 可以合并 list、tuple、iterator 中的元素,效率比连接符 + 高。

  • 10、使用 while 1while True 更快。

  • 11、使用 **pow 快 10 倍以上。

  • 12、使用迭代器和生成器代替列表等数据结构效率更高,使用列表(字典)解析式和生成器表达式比用循环效率更高。

  • 13、避免在循环中用 + 或 += 来连续拼接字符串。因为字符串是不变型,这会毫无必要地建立很多临时对象,从而成为二次方级别的运算量而不是线性运算时间。

  • 14、多去了解标准库,标准库中用很多好用的功能,能够更优雅的解决问题,如 pkgutil.get_data()、operator.methodcaller() 等等。


Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in das Python-Codierungsformat (mit Beispielen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen