ホームページ  >  記事  >  バックエンド開発  >  Python コーディング形式の詳細な紹介 (例付き)

Python コーディング形式の詳細な紹介 (例付き)

不言
不言転載
2019-01-28 10:56:453628ブラウズ

この記事では、Python のコーディング形式について詳しく説明します (サンプル付き)。一定の参考価値があります。困っている友人は参考にしてください。お役に立てれば幸いです。

コードは実行だけでなく読み取りにも使用されます。コードを読みやすくするために、多くのプログラミング言語には独自のコーディング標準があります。仕様はコードの一貫性を維持し、コードをより美しく読みやすくするために開発されています。コードをどのようにフォーマットして記述するかは絶対的なものではないため、一部の領域では議論の余地があります。スタイルガイドが適用されない場合もあります。最も重要なことは、いつ一貫性を欠くかを知ることです。何をすべきかわからない場合は、他の例を参考にしてください。

この記事は Python コーディング スタイルの単なる参考資料であり、必ずこのようにしなければならないというルールではありません。この記事の目的は、開発者がより読みやすいコードを作成できるようにガイドするためのガイドとして機能することです。

1. コード レイアウト

主にインデントと空白行のレイアウト:

  • 1. インデントには 4 つのスペースを使用します。 (どのエディタでもこの機能を実行できます)、タブ文字は推奨されず、タブ文字とスペースを混合することはできません。

  • 2. 各行は 80 文字を超えてはなりません。改行にはバックスラッシュを使用できますが、角かっこを使用することをお勧めします (Python は暗黙的に接続されます)。

  • 3. クラスと最上位関数定義の間には 2 つの空白行があり、クラス内のメソッド定義の間には 1 つの空白行があり、クラス内の論理的に無関係な段落の間には 1 つの空白行があります。関数; 他の場所で繰り返さないようにしてください。空白行。

主にソース コード ファイル全体のレイアウト:

  • 1. モジュール コンテンツの順序: モジュールの説明、モジュールのドキュメント文字列、インポート ステートメント、グローバル変数または定数、およびその他の定義。

  • 2. モジュール インポート パーツの順序: 標準ライブラリ、サードパーティ モジュール、カスタム モジュール; 各パーツの間には空白行があります。

  • 3. import os, sys などの 1 つのインポート ステートメントで複数のモジュールを一度にインポートしないでください。推奨されません。

  • 4. モジュールをインポートするときは、名前の競合を避けるために適切な方法を使用する必要があります。たとえば、適切な場合にのみ from xx import xx を使用し、回避するようにしてください。 ## を使用します。#from xx imoprt *

  • 5. 自作モジュールで

    from xx import * を使用する必要がある場合は、import ステートメントの後に __all__# を使用するか、 ## インポート ルールを制限するメカニズム。

  • 3. ステートメントの配置

    1. 通常、各ステートメントは独自の行に配置する必要があります。
  • 2. 行の最後にセミコロンを追加したり、複数のステートメントを同じ行に置くためにセミコロンを使用したりしないでください。
  • 3. if/for/while ステートメントでは、実行ステートメントが 1 つしかない場合でも、新しい行を開始するようにしてください。
  • 4. 行接続を実装するために使用される場合を除き、return ステートメント (return) または条件ステートメント (if/for/while) では括弧を使用しないでください。
  • 5. if ステートメントの場合、else がなく、ステートメントが比較的短い場合は、1 行で完了できます (ただし、推奨されません)。例:
  • if foo: bar(foo)

    .

  • 6. 単純なクラス定義の場合は、例外を定義するなど、1 行で完了することもできます (ただし、推奨されません)。 ##class UnfoundError(Exception): pass
  • .

    7. 関数とメソッドには、垂直方向の暗黙的なインデントを使用するか、かっこ内で吊り下げインデントを使用します。
  • # 一行写不下时,有括号来连接多行,后续行应该使用悬挂缩进
    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. スペースには
の一般原則を使用し、不要なスペースは避けてください。

1. さまざまな右括弧の前にスペースを追加しないでください。
  • 2. コンマ、コロン、セミコロンの前にスペースを追加しないでください。スペースはそれらの後に追加する必要があります (行末を除く)。
  • 3. 関数の左括弧の前にスペースを追加しないでください。 Func(1) など。
  • 4. シーケンスの左括弧の前にスペースを追加しないでください。リスト[2]など。
  • 5. 演算子の左右にスペースを追加します。位置揃えのためにスペースを追加しないでください。
  • 6. 関数のデフォルトパラメータで使用される代入文字の周囲のスペースを省略します。
  • 良いスタイル:
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)
悪いスタイル:

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. コメント

一般原則、間違ったコメントコメントはありません。したがって、コードの一部が変更された場合、最初に行うことはコメントを変更することです。コメントはできるだけ英語で記述してください。最初の文字を大文字にして、完全な文を使用するのが最善です。文の後にはターミネータが必要です。ターミネータの後には 2 つのスペースを入れて次の文を開始してください。フレーズの場合、ターミネータは省略できます。コメントのコンテンツを開始する前に、コメントの前に

# の後にスペースを入れる必要があります。

1. ブロック コメントは、コードの前に追加されるコメントです。段落間には「#」のみの行を使用します。例:
  • # Description : Module config.
    #
    # Input : None
    #
    # Output : None
2. 行コメント、コード行の後にコメントを追加します。コメントを開始する前に、ステートメントの後にスペースを 2 つ残すようにしてください。連続した行コメントがある場合、見栄えを考慮して「#」を揃えることができます。ステートメントが長い場合は、行コメントの使用をできるだけ少なくする必要があります。例えば:###
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() 等等。


以上がPython コーディング形式の詳細な紹介 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。