Python pep8コーディング仕様とコードデバッグ(pdb、ipdb、debug)

Python pep8コーディング仕様とコードデバッグ(pdb、ipdb、debug)

1. Pythonのpep8エンコーディング仕様

通常、PEP8について言及しているようですが、具体的には何ですか?「Python拡張提案#8」(Python拡張提案No. 8)は、PEP8とも呼ばれ、Python用にコンパイルされたコード形式ガイドです。

プログラミング言語は芸術ではなく、作品やツールであるため、一連のコーディング標準を体系化し、それに従う必要があります。

1.インデントレベルごとに4つのスペースを使用します。
2. 1行あたり最大79文字。
3.トップレベル関数(def)またはクラス(class)の定義の間に2つの空行があります。
4. ASCIIまたはUTF-8エンコードファイルを使用します。(これは、エンコード形式、ASCIIエンコード形式、またはUTF-8エンコード形式を示します)
5.ファイルの上部のコメントとドキュメントの下に、インポートステートメントごとに1行につき1つのモジュールのみがインポートされ
、標準ライブラリ、サードパーティライブラリとローカルライブラリのインポート順序がグループ化されています。(標準ライブラリはpythonをダウンロードすると利用可能になります。つまり、pythonに付属しています。ダウンロードが必要な場合は、pipかどうかに関係なく、サードパーティのライブラリです。ローカルライブラリは自分で作成します)
6.括弧内、中かっこの間または角かっこの前に余分なスペースはありません。7
クラスの名前(CamelCase)はクラスの名前に使用されます。例外の定義はエラープレフィックスです(該当する場合)。関数の名前は、アンダースコアで区切られた小文字です。 Separated_by_underscoresなど; _privateなどのアンダースコア付きのプライベートプロパティまたはメソッドの定義

コード標準を自動的にチェックするPep8ツール

pep8はどの行がpep8に違反しているのかを示し、各問題のエラーコードを提供します。必要なコンプライアンスルールに違反している場合、pはエラーをバーストします(Eで始まるエラーコード)。微妙な問題の場合は、警告(Wで始まる
エラーコード)が報告されます。文字に続く3桁はエラーまたは警告で、おおよそのエラーカテゴリを確認できます。例えばE2オープン
ヘッドスペースとエラーは通常、通常、3行の空白行に関連したミスの先頭に関連しており、これのW6始まりを警告すると、そのすでに示し
時代遅れを通じて機能を。

コードレイアウト

1.1インデント

  • インデントのレベルごとに4つのスペース
  • かっこ内で垂直暗黙インデントまたはぶら下げインデントを使用します
  • タップを使用しないでください。タップとスペースを混ぜないでください
正しいデモ
# (垂直隐式缩进)对准左括号起的第一个字符
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# (悬挂缩进) 以行首字符为基准,缩进(一般情况只需一层缩进)
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)

# 右括号回退
my_list = [
    1, 2, 3,
    4, 5, 6,
]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
)123456789101112131415161718192021222324
エラーのデモ
# 使用悬挂缩进时,第一行有参数。
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)

# 右括号不回退,不推荐
my_list = [
    1, 2, 3,
    4, 5, 6,
    ]

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

1.2最大線幅

  • 各行の最大行幅が79文字を超えない
  • 括弧なしで行を継続し、バックスラッシュを使用します
  • 括弧内の継続のためにバックスラッシュを使用する必要はありません
# 无括号续行, 可使用反斜杠
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())

# 括号内续行,尽量在运算符后再续行
class Rectangle(Blob):
    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == 'red' and emphasis == 'strong' or
                highlight > 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so, values are %s,%s"%                             (width, height))12345678910111213141516

1.3 空行

  • 2つの空白行は、トップレベルの関数とクラスの定義を分割するために使用されます
  • クラス定義でメソッドを分割するために単一の空白行が使用されます
  • 関数内の論理に依存しない段落間の空白行;他の場所では行を空白にしないようにしてください
  • 「;」を使用できますが、同じ行に複数のステートメントを記述しないようにしてください
  • if / for / whileステートメントでは、実行ステートメントに文が1つしかない場合でも、新しい行になければなりません。
class A(object):     # 类的方法定义用单个空行分割
    def method1():
        pass

    def method2():
        pass

def method3():       # 两行空行分割顶层函数和类的定义
    pass12345678910

1.4モジュールのインポート

  • インポートされた各モジュールは別々の行にある必要があります
  • インポートシーケンスは次のとおりです。最初に標準ライブラリ、次に関連するサードパーティライブラリ、最後にローカルライブラリ。(異なるタイプのモジュールの間には空白行がなければならず、各グループのモジュールの順序は最初の文字から昇順です)
# 正确示范
import active   # 按模块首字母排序导入, 依此递推
import adidas
import create

# 错误示范
import sys, os, knife  # 错误:一行导入多模块

import create          # 错误:不按模块首字母导入
import active
import beyond1234567891011

1.5文字列

一重引用符と二重引用符は同じ効果がありますが、ペアで存在することが保証されている必要があり、混在させることはできません。
(文章には二重引用符を、単語には一重引用符を使用することをお勧めしますが、必須ではありません。)

# 单引号和双引号效果一样

name = 'JmilkFan'
name = "Hey Guys!"1234

1.6式とステートメントのスペース

大括弧の間にスペースを入れない
spam(ham[1], {eggs: 2})        # 正确示范

spam( ham[ 1 ], { eggs: 2 } )  # 错误示范123
カンマ、コロン、セミコロンの前のスペースは避けてください
if x == 4: print x, y; x, y = y, x       # 正确示范

if x == 4 : print x , y ; x , y = y , x  # 错误示范123
関数呼び出しの左括弧の前にスペースがあってはなりません
spam(1)
dct['key'] = lst[index]     # 正确示范

spam (1)
dct ['key'] = lst [index]   # 错误示范12345
割り当ておよびその他の演算子は、配置の前後に複数のスペースを追加できません
x = 1                # 正确示范
y = 2
long_variable = 3

x             = 1    # 错误示范
y             = 2
long_variable = 31234567
2項演算子の両側にスペースを置きます
  • =(+ =、-=など)を含む複合演算子
  • 比较操作符(==、<、>、!=、<>、<=、> =、in、not in、is、is not)
  • 論理演算子(and、or、not)
a = b
a or b

# 括号内的操作符两边不需要空格
name = get_name(age, sex=None, city=Beijing)12345

1.7注意事項

一般的に、コメントが間違っている方がコメントがないよりはましです。したがって、コードの一部が変更された場合、最初に行うのはコメントの変更です。

  • コメントブロック
    • コメントブロックは通常、コードの前に適用され、コードと同じインデントを持っています。各行は「#」で始まり、#の後にスペースが1つあります。段落は「#」のみの行で区切られます
# Have to define the param `args(List)`, 
# otherwise will be capture the CLI option when execute `python manage.py server`.
# oslo_config: (args if args is not None else sys.argv[1:])
CONF(args=[], default_config_files=[CONFIG_FILE])1234
  • 単一行コメント(この方法はできるだけ使用しないでください)
x = x + 1 # Compensate for border1
  • Docstring
# 多行文档, 首行首字母大写,结尾的 """ 应该单独成行
"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""

# 单行的文档, 结尾的 """ 在同一行。
"""Return a foobang"""1234567
  • 共有モジュール、関数、クラス、メソッドのドキュメント文字列を記述します。ドキュメント文字列を記述するために非共有は必要ありませんが、コメントを書き込むことができます(defの次の行に)
  • 不要なコメントを避ける

1.8命名規則

  • パッケージとモジュールの名前
    パッケージとモジュールの名前は短く、すべて小文字にする必要があります。複数のアンダースコアを1つのアンダースコアで接続できます。
  • クラス名はこぶ名に
    続きます。
class MyClass(object):
    pass12
  • グローバル変数名
    グローバル変数名は、可能な限りモジュール内でのみ使用する必要があります。ステートメントを使用してfrom moduleName import variableNameインポートできるモジュールの場合__all__メカニズムを使用してグローバル変数が他のモジュールによってインポートされないようにするか、グローバル変数名の先頭にアンダースコアを追加する必要があります。
_name = 'name'1
  • 関数名
    関数名はすべて小文字の凹のこぶの規則でなければなりません。
vcenter_connection = ''1
  • 定数名
    定数はすべて大文字の凹型のこぶの規則で表され、通常はモジュールの一番上のセルで定義されます。
MAX_OVERFLOW = ''
TOTAL = 112
  • メソッド名とインスタンス変数
    • 非パブリックメソッドとインスタンス変数の先頭にアンダースコアを使用する
    • 場合によっては、サブクラスの名前付けとの競合を回避するために、2つの先行アンダースコア
      に注意する必要があります。クラスFooの属性名がaの場合、Foo.aの方法で属性にアクセスできません(永続的なユーザーは、 (Foo._Foo__aを介してアクセスされます)。したがって、通常、二重の先行アンダースコアは、基本クラスのプロパティとの名前の競合を回避するためにのみ使用されます。

2.プログラミングの提案

  • コーディングでは、演算子「+」はCPythonでは非常に効率的ですが、Jythonでは非常に低いなど、他のPython実装の効率を考慮する必要があります。
  • Noneの比較では、==の代わりにisまたはisを使用します。可能な場合は常に '=='の代わりに 'is''is not'を使用します。使用するのはnotではなくnot ...です。前者の方が読みやすいです
if foo is not None     # Yes

if not foo is None     # No123
if x is not None       # if x is not None 要优于if x

if x123
  • ラムダの代わりに関数定義キーワードdefを使用して識別子を割り当てます。これは、コールバックと文字列表現により適しています。
def f(x):              # Yes
    return 2*x

f = lambda x: 2*x      # No1234
  • 例外クラスは、BaseExceptionではなく、Exceptionから継承する必要があります。例外をキャッチするときは、特定の例外を指定してみてください。Exception以外は使用しないでください。問題ではなく、キャッチする必要があるもの
try:                                   # Yes (捕获具体异常)
    import platform_specific_module    
except ImportError:
    platform_specific_module = None

try:                                   # No (不要全局捕获)
    import platform_specific_module
except:
    platform_specific_module = None123456789
  • try / except句のコードは、他のエラーのシールドを回避するために可能な限り小さくする必要があります
try:                            # Yes
    value = collection[key]
except KeyError:
    return key_not_found(key)
else:
    return handle_value(value)

try:                            # No
    return handle_value(collection[key])
except KeyError:
    # 可能会捕捉到handle_value()中的 KeyError, 而不是collection的
    return key_not_found(key)12345678910111213
  • 戻り値がない場合、関数またはメソッドはNoneを返す必要があります
def foo():        # Yes
    return None

def foo():        # No
    return12345
  • 文字列モジュールPython 2.0の代わりに文字列メソッドを使用します
    。文字列メソッドはその後常に高速になり、Unicode文字列と同じAPIを使用します
  • 文字列スライスの代わりに.startswith()と.endswith()を使用して、プレフィックスとサフィックスを確認します
    。startswith()とendwithはより簡潔で、エラーを減らすのに役立ちます
if foo.startswith('bar'):   # Yes

if foo[:3] == 'bar':        # No123
  • isinstance()を使用してオブジェクトタイプを比較する
if isinstance(obj, int):   # Yes

if type(obj) is type(1):   # No123
  • 空または空でない配列を解析
    FalseにBOOL空シーケンス型オブジェクト:
if not seq:       # Yes
   pass
if seq:
   pass

if len(seq):      # No
   pass
if not len(seq):
   pass123456789
  • ブール比較に==を使用しないでください
 # Yes
if greeting:          
   pass

# No
if greeting == True
   pass
if greeting is True: # Worse
   pass123456789
  • 文字列をスペースで終了しないでください
  • バイナリデータの判定if boolvalue方法
  • MapとReduceを使用し、ループは使用しないでください

第二に、pdbコードのデバッグ

プログラムを1回記述して正常に実行できる確率は非常に低く、基本的に1%を超えません。修正が必要なさまざまなバグが常に存在します。いくつかのバグは非常に単純です。エラーメッセージを見るとわかります。いくつかのバグは非常に複雑です。エラーが発生した場合、正しい変数値と間違っている変数値を知る必要があります。バグを修正します。

ipdbライブラリをインストールする

PS G:\四期\python> pip install pdb

G:\ Fourth Phase \ python \ 4 \ 1.pyファイルの内容は次のとおりです。

import pdb
s = '0'
n = int(s)
pdb.set_trace()
print(10/n)

デバッグ

PS G:\四期\python\4> python 2.py
> g:\四期\python\4\2.py(5)<module>()
-> print(10/n)

1. pdbをデバッグに使用します。

pdbはPythonに付属するパッケージです。Pythonプログラムにインタラクティブなソースコードデバッグ機能を提供します。主な機能には、ブレークポイントの設定、シングルステップデバッグ、関数デバッグの開始、現在のコードの表示、スタックフラグメントの表示、変数の動的な変更などがあります。値など pdbは、一般的に使用されるいくつかのデバッグコマンドを提供します。詳細については、表1を参照してください。

pdbの一般的なコマンド

コマンド 説明する
breakまたはbブレークポイントを設定します ブレークポイントを設定する
続行またはc プログラムを実行し続ける
リストまたはl 現在のコード行を表示する
ステップまたはs エントリー機能
リターンまたはr 現在の関数から戻るまでコードを実行する
終了またはq 中止して終了
次またはn 次の行を実行
pp 変数の値を出力する
助けて 助けるために

以下は、pdbを使用して特定の例をデバッグする方法を説明しています。

2.サンプルテストコード

 import pdb 
 a = "aaa"
 pdb.set_trace() 
 b = "bbb"
 c = "ccc"
 final = a + b + c 
 print final

デバッグを開始します。スクリプトを直接実行します。スクリプトはpdb.set_trace()に留まり、n + Enterを選択して現在のステートメントを実行します。初めてn + Enterキーを押した後、Enterキーを直接押して、最後のデバッグコマンドを繰り返すことができます。

(1)pdbによるデバッグ

[root@rcc-pok-idg-2255 ~]#  python epdb1.py 
 > /root/epdb1.py(4)?() 
 -> b = "bbb"
 (Pdb) n 
 > /root/epdb1.py(5)?() 
 -> c = "ccc"
 (Pdb) 
 > /root/epdb1.py(6)?() 
 -> final = a + b + c 
 (Pdb) list 
  1     import pdb 
  2     a = "aaa"
  3     pdb.set_trace() 
  4     b = "bbb"
  5     c = "ccc"
  6  -> final = a + b + c 
  7     print final 
 [EOF] 
 (Pdb) 
 [EOF] 
 (Pdb) n 
 > /root/epdb1.py(7)?() 
 -> print final 
 (Pdb)

デバッグの終了:現在のデバッグを終了するには、quitまたはqを使用しますが、quitは非常に失礼な方法でプログラムを終了し、その結果、直接クラッシュします。

(2)デバッグを終了する

[root@rcc-pok-idg-2255 ~]#  python epdb1.py 
 > /root/epdb1.py(4)?() 
 -> b = "bbb"
 (Pdb) n 
 > /root/epdb1.py(5)?() 
 -> c = "ccc"
 (Pdb) q 
 Traceback (most recent call last): 
  File "epdb1.py", line 5, in ? 
    c = "ccc"
  File "epdb1.py", line 5, in ? 
    c = "ccc"
  File "/usr/lib64/python2.4/bdb.py", line 48, in trace_dispatch 
    return self.dispatch_line(frame) 
  File "/usr/lib64/python2.4/bdb.py", line 67, in dispatch_line 
    if self.quitting: raise BdbQuit 
 bdb.BdbQuit

変数の値を出力する:デバッグ中に変数の値を出力する必要がある場合は、pと変数名を直接使用できますが、特定の値は現在のステートメントが実行された後でしか表示されないことに注意してください。レポートNameError:<exceptions.NameError…....>エラー。

(3)デバッグ中に変数を出力する

[root@rcc-pok-idg-2255 ~]#  python epdb1.py 
 > /root/epdb1.py(4)?() 
 -> b = "bbb"
 (Pdb) n 
 > /root/epdb1.py(5)?() 
 -> c = "ccc"
 (Pdb) p b 
'bbb'
 (Pdb) 
'bbb'
 (Pdb) n 
 > /root/epdb1.py(6)?() 
 -> final = a + b + c 
 (Pdb) p c 
'ccc'
 (Pdb) p final 
 *** NameError: <exceptions.NameError instance at 0x1551b710 > 
 (Pdb) n 
 > /root/epdb1.py(7)?() 
 -> print final 
 (Pdb) p final 
'aaabbbccc'
 (Pdb)

現在のデバッグを停止してプログラムの実行を続行するには、cを使用します。次のプログラムでset_statement()が引き続き宣言されている場合は、デバッグ状態に戻ります。読者はコードが最終的に出力される前に確認するためにset_trace()を追加できます。

(4)デバッグを停止し、プログラムの実行を続行します

[root@rcc-pok-idg-2255 ~]#  python epdb1.py 
 > /root/epdb1.py(4)?() 
 -> b = "bbb"
 (Pdb) n 
 > /root/epdb1.py(5)?() 
 -> c = "ccc"
 (Pdb) c 
 aaabbbccc

コードの表示:デバッグ時に現在のコードブロックを覚えておく必要はありません。特定のコードブロックを表示する場合は、listコマンドまたはlコマンドを使用して表示できます。リストは、現在のデバッグ文を指すために矢印->を使用します。

(5)デバッグ中にコードを表示する

[root@rcc-pok-idg-2255 ~]#  python epdb1.py 
 > /root/epdb1.py(4)?() 
 -> b = "bbb"
 (Pdb) list 
  1     import pdb 
  2     a = "aaa"
  3     pdb.set_trace() 
  4  -> b = "bbb"
  5     c = "ccc"
  6     final = a + b + c 
  7     pdb.set_trace() 
  8     print final 
 [EOF] 
 (Pdb) c 
 > /root/epdb1.py(8)?() 
 -> print final 
 (Pdb) list 
  3     pdb.set_trace() 
  4     b = "bbb"
  5     c = "ccc"
  6     final = a + b + c 
  7     pdb.set_trace() 
  8  -> print final 
 [EOF] 
 (Pdb)

関数使用時のデバッグ

(6)関数の使用例

import pdb 
 def combine(s1,s2):      # define subroutine combine, which... 
    s3 = s1 + s2 + s1    # sandwiches s2 between copies of s1, ... 
    s3 = '"' + s3 +'"'   # encloses it in double quotes,... 
    return s3            # and returns it. 
 a = "aaa"
 pdb.set_trace() 
 b = "bbb"
 c = "ccc"
 final = combine(a,b) 
 print final

デバッグに直接nを使用する場合、final = Combine(a、b)を使用すると、通常の割り当てステートメントとして扱われ、print finalと入力します。関数をデバッグする場合、その処理方法は?sを直接使用して関数ブロックに入ることができます。関数のシングルステップデバッグは、上記の概要と似ています。関数をステップ実行したくない場合は、ブレークポイントで直接rを押して、呼び出し元の場所に移動できます。

(8)関数をデバッグする

[root@rcc-pok-idg-2255 ~]# python epdb2.py 
 > /root/epdb2.py(10)?() 
 -> b = "bbb"
 (Pdb) n 
 > /root/epdb2.py(11)?() 
 -> c = "ccc"
 (Pdb) n 
 > /root/epdb2.py(12)?() 
 -> final = combine(a,b) 
 (Pdb) s 
 --Call-- 
 > /root/epdb2.py(3)combine() 
 -> def combine(s1,s2):      # define subroutine combine, which... 
 (Pdb) n 
 > /root/epdb2.py(4)combine() 
 -> s3 = s1 + s2 + s1    # sandwiches s2 between copies of s1, ... 
 (Pdb) list 
  1     import pdb 
  2 
  3     def combine(s1,s2):      # define subroutine combine, which... 
  4  ->     s3 = s1 + s2 + s1    # sandwiches s2 between copies of s1, ... 
  5         s3 = '"' + s3 +'"'   # encloses it in double quotes,... 
  6         return s3            # and returns it. 
  7 
  8     a = "aaa"
  9     pdb.set_trace() 
 10     b = "bbb"
 11     c = "ccc"
 (Pdb) n 
 > /root/epdb2.py(5)combine() 
 -> s3 = '"' + s3 +'"'   # encloses it in double quotes,... 
 (Pdb) n 
 > /root/epdb2.py(6)combine() 
 -> return s3            # and returns it. 
 (Pdb) n 
 --Return-- 
 > /root/epdb2.py(6)combine()->'"aaabbbaaa"'
 -> return s3            # and returns it. 
 (Pdb) n 
 > /root/epdb2.py(13)?() 
 -> print final 
 (Pdb)

デバッグ中に値を動的に変更します。次の例に示すように、変数の値はデバッグ中に動的に変更できます。bが割り当てられているため、以下のエラーがあることに注意してください。bの割り当てを変更する場合は、それを使用する必要があります。B.

(7)デバッグ中に動的に値を変更する

[root@rcc-pok-idg-2255 ~]# python epdb2.py 
 > /root/epdb2.py(10)?() 
 -> b = "bbb"
 (Pdb) var = "1234"
 (Pdb) b = "avfe"
 *** The specified object '= "avfe"' is not a function 
 or was not found along sys.path. 
 (Pdb) !b="afdfd"
 (Pdb)

補足

  • コマンドラインからデバッグモードに入るには:python -m pdb demo.py
  • デバッグモードでEnterキーを押して、前のコマンド実行します
  • ipythonでPDBを使用する(エクスペリエンスの向上):%run -d demo.py

リファレンス1

リファレンス2

おすすめ

転載: blog.51cto.com/14320361/2488895