何年にもわたって、私が書くほどPythonになるほど、私は自分自身の理由で一貫して意図的にいくつかを破っていますが、ほとんどのガイドラインに同意するようになります。
私は、PEP 8(または他のPEPでも)の人々が信心深く固執している理由とその理由、そして人々が不便または不適切だと思うものを知りたいと思います。
私の場合(そして一般的に仕事で)、私たちが逸脱していることはほんの一握りです:
アンダースコアで区切られた小文字の名前は、間違いなく一貫しているので、その意味を確認できますが、いくつかの不整合(部分的または誤って大文字になっている頭字語や続く単語など)が導入される場合でも、lowerCamelCaseを使用する傾向があります。多くの場合、瞬間的な呼び出しになります)。主に、私たちが日常的に使用しているAPIのほぼ全体がキャメルケース(一部は上部、一部は下部)を使用しているため、また何らかの理由で読みやすく、アンダースコアを分離トークンまたは規定のマングリング/不明瞭化として予約する傾向があるためです。
私はまだ、PEPがオブジェクトの内部で規定している方法で物事の間隔を空けることができません。 newとinitクラス名と引数、クラス内の同じ機能範囲に寄与するメソッド(init、get、setなど)を使用して常に読みたいので、空白行なしでクラスのすぐ下に残す傾向があります。同じ属性または属性のセットの)私は単一スペースだけ離れており、クラス間の3つのスペースと、そのオブジェクトのマップに精神的に集約されないメソッド間の2つのスペースが好きです。これもまた、純粋にコードの視覚的な影響と読みやすさのためです。フロー制御内の非常にコンパクトなコンテンツと、メソッドとオブジェクトの間のこの種の間隔は、コードがパークされてから数か月後に再読み取りを実行したい場所に一貫して正確に目を向けます。また、選択したエディターでの折りたたみにもよく反応します。
代わりに私が固執するいくつかのことは、他の方法で書かれたものを読んだときに私を狂わせますが、スペースではなくタブです(特に、私たちが使用する一部のアプリ内エディターが実際にはタブ置換機能を備えていない場合、プロトタイピング段階)。
インポートなどの順序、およびインポート、グローバルなど。大量のインポートが混在している、または順序が狂っているファイルでは、本当に気が遠くなります。
ステートメント内の空白、特にタブを使用していて、変数名の異なる長さの行全体で代入演算を整列させようとする場合(そして、Excelに見えるコードの一部が見栄えが悪いことをそれを実行する人に説得する方法はないようです;)) 。
そして、特に同じフロー制御ブロック内に明らかにランダムな間隔があり、オブジェクト内でメソッドに使用される間隔が同じである場合は、制御ブロック内の間隔。いまいましいことを読み始める前に、それらを編集せざるを得ません。
ですから、それらは私のものであり、PEPの私の「違反」の背後にある理由です(一部は共有され、一部は同僚に眉をひそめています)。私は、他のPythonistaがそれらの点で何をし、何をしないかを読むことに非常に興味があります。
「1行あたり79文字」の部分はナンセンスです。彼らの非常に独自の例は、これを行うと判読不能なコードになる方法を示しています。
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))
Blob.__init__(self, width, height,
color, emphasis, highlight)
それは試してみるようなものです-
読む
ニュースアーティ-
cleが書かれました
このような。
80カラムの端末は、10年以上にわたって深刻な開発環境ではありませんでした。不具合のある80x25環境からピンチで編集する必要がある場合、エディターのラッピングはマイナーな不便です。それを避けるために、通常の開発中にコードを損傷するつもりはありません。
120列の折り返しは、現代の開発には完全に賢明であり、140でも問題はありません。このガイドラインは廃止されており、それに従うと、醜くて読みにくいコードになります。
PEP8は、「割り当て(または他の)演算子の周囲に複数のスペースを配置して別の演算子に揃える」ことや、数学演算子の周囲に「複数のスペースを使用しない」ことを避けるように言っていますが、私はこれに従いません。
隣接する行が関連しているか非常に類似しているが、まったく同じではない場合は、「余分な空白」を追加することがよくあります。
search_start = (f - f_1/3) * n/fs
search_stop = (f + f_1/3) * n/fs
b_lpf, a_lpf = filter(N, 2*pi*fc, 'low', analog=True)
b_hpf, a_hpf = filter(N, 2*pi*fc, 'high', analog=True)
p[x > 1] = np.cosh(order * np.arccosh( x[x > 1]))
p[x < -1] = (1 - 2 * (order % 2)) * np.cosh(order * np.arccosh(-x[x < -1]))
b0 = (1 + cos(w0))/2
b1 = -(1 + cos(w0))
同様に、 数値の配列に対するコードスタイルの警告 が、通常はライブラリ自体によってフォーマットされている読みやすい方法でフォーマットされているのは不愉快です:
a = array([[-0.198, 0.248, -1.17 , -0.629, 1.378],
[-1.315, 0.947, -0.736, -1.388, 0.389],
[ 0.241, -0.98 , 0.535, 0.951, 1.143],
[-0.601, 1.286, -0.947, 0.037, -0.864],
[ 0.178, -0.289, -1.037, -1.453, -0.369]])
これにより、多数のE201 E202E222違反が発生します。
PEP8では、読みやすさを向上させたとしても、カンマの前または角かっこの後ろに余分な空白をできないことができないため、このように書式設定することをお勧めします。
a = array([[-0.198, 0.248, -1.17, -0.629, 1.378],
[-1.315, 0.947, -0.736, -1.388, 0.389],
[0.241, -0.98, 0.535, 0.951, 1.143],
[-0.601, 1.286, -0.947, 0.037, -0.864],
[0.178, -0.289, -1.037, -1.453, -0.369]])
PEP8 言う
最も重要なことに、複数行のdocstringを終了する「」は、それ自体が1行にあり、前に空白行が付いていることが望ましいことに注意してください。例:
"""Return a foobang Optional plotz says to frobnicate the bizbaz first. """
これは単なる「余分な空白」であり、明確な理由もなく、開始引用と終了引用を異なる方法で処理するため、これはかなり奇妙だと思います。
根拠は PEP 257 にあります:
BDFLは、複数行のdocstringの最後の段落とその終了引用符の間に空白行を挿入し、終了引用符を単独で1行に配置することをお勧めします。この方法で、Emacsのfill-paragraphコマンドを使用できます。
Emacs、本当に?誰もが特定の編集ツールの特定のコマンドの特異性に応えるために奇妙なことをするべきですか?
また、終了引用符は独自の行にあると主張しながら、引用符と同じ行にdocstringの先頭を置くのは奇妙だと思います(必須ではありませんが、推奨されます)。これはより論理的であり、単一行と複数行の両方のドキュメント文字列に使用する必要があると思います。
def foobang(bizbaz, plotz=None):
"""
Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""
if plotz is not None:
...
更新:太字の部分が削除され、「終了引用符を1行に単独で配置する」と表示され、「要約行」と表示されます。冒頭の引用符と同じ行または次の行にある可能性があります。」.
私はこれに同意しません:
- Imports should usually be on separate lines, e.g.:
Yes: import os
import sys
No: import sys, os
私はいつも簡単なインポートを一緒に書いています。それらをすべて別の行に記述する利点はありません。すべてのソースファイルの上部に膨らみを追加し、境界線であるものに簡潔で入力しやすいものに変換するだけですboilerplate、例えば。非常に冗長なものであるため、他のファイルからコピーして貼り付けたくなるものです。
これはすぐに読みやすく、理解できます。
import sys, os, time, gc, inspect, math, doctest
それは短く、簡単にスキムでき、簡単に追加できます。もちろん、1行に多すぎる場合、またはimport
インポートが必要な場合は、複数のfrom
ステートメントを使用します。
私もdo通常、標準ライブラリのインポートを、自分のモジュールや他のライブラリのインポートとは別に保持します。これは、PEP8が推奨するグループ化の概念に同意します。
標準は重要であり、PEP8は私が主張する非常に優れたスタイルガイドです。私が同意しない唯一のガイドラインは、数学演算子の周りの間隔です。 たとえば、PEP8は次の間隔を要求します
Without PEP8 With PEP8
----------------------------------------------------------------
y = sqrt(x**2 + y**2) y = sqrt(x ** 2 + y ** 2)
a*x**3 + b*x**2 + c*x + d a * x ** 3 + b * x ** 2 + c * x + d
10**(a*x + b) 10 ** (a * x + b)
F = V/(sqrt(g*h) + epsilon) F = V / (sqrt(g * h) + epsilon)
a*cos(nx/pi) + b*sin(nx/pi) a * cos(nx / pi) + b * sin(nx / pi)
私は適合しようとしていますが、これは私が苦労している1つの領域です。 PEP8の間隔により数学が読みにくくなると他の誰かも感じていますか?
更新:
PEP8 だった 修正済み 左側のフォーマットを推奨し、右側のフォーマットを推奨しない:
はい:
i = i + 1 submitted += 1 x = x*2 - 1 hypot2 = x*x + y*y c = (a+b) * (a-b)
番号:
i=i+1 submitted +=1 x = x * 2 - 1 hypot2 = x * x + y * y c = (a + b) * (a - b)
私の会社のスタイルガイドラインでは、スペースではなくタブが特に求められています。 PEP 8は、スペースが望ましいことを示唆していますが、反対のことがわかりました。私はVIMでコードが4 'スペース'インデントされているのを見るのが好きです。同僚はEmacsで8 'スペース'を好みます。 タブを使用すると、両方のエディターを設定して、好みに応じてコードを表示できます。
他のCベースの言語では、インデントは実際には単なる書式設定ですが、Python インデントは構文であるため、_indentation level 2
_を表す必要があると感じます何か(つまりスペース)の_2
_または_4
_ではなく、何か(つまりタブ)の_8
_によって。
インデント文字の選択はおそらく元の聖なる炎の戦争(VIM/Emacs炎の戦争の前であっても)であるため、意見を表明するための忘却に改造されることを期待しています主題について!
複数行の条件など:PEP-8は、前ではなく二項演算子を中断するように明示的に指示します後。その魅力が見えないのではないかと思います。条件付きの前に中断する方がはるかに理にかなっているため、折り返し/継続された行では、各サブ行が条件付きで始まります。
if (condition1 \
or condition2 \
or condition3):
do_something()
ご覧のとおり、サブラインにインデントを追加して、下のブロックから視覚的にオフセットされるようにします。 PEP-8はこれについて明確なことは何も述べていませんが(そうですか?)、例では、サブラインが開き括弧と並んでいます。
PEP 8は言う:
はい:
x = 1
y = 2
long_variable = 3
番号:
x = 1
y = 2
long_variable = 3
私は通常それに従いますが、読みやすくするために別のバリアントを使用することもあります。
x = 1
y = 2
long_variable = 3
私の「違反を認める」は「もし」についてです
PEP8は1行に複数のステートメントを記述しないため、これを実行する必要がある場合は、次のようになります。
if cond:
actions
...
ただし、アクションが1つしかない場合は、すべてを1行にすることをお勧めします。私は好きです:
if a == 0: b = 0
より:
if a == 0:
b = 0
PEP 8の「問題」は、ほとんどのプログラマーにとって非常に大きな感情にさらされる個人的な好みの領域を踏むことです。
私個人としては、キャメルケースとアンダースコア、および列の配置ディレクティブは常に問題でした。ここでは他の多くの回答にもポイントがあり、PEP 8を意図的に破ることもあります。その特定の場合、それは単に「理にかなっている」からです。
私のPythonプログラミングキャリアの中で、PEP 8をあきらめて(使用して)に向けたときのポイントがありました。ほとんどのアイテムにとって比較的簡単でした。列の配置。これは厄介すぎて従うことはできません(とにかく私は嫌いですが)。とにかく、私の「あきらめ」の結果として、私のコードは今や同僚にとってはるかに読みやすくなっています-そして驚くべきことに:私にも(列の配置を除いて:p)。
python自体:2.x(非準拠)と3.x(準拠)の間)についてPEP 8が行ったことも認識する必要があります。「常に知る」ことはずっと簡単です。特定の関数の名前は、Pythonの「バッテリー」がより適切にソートされます。
私は常に4つのスペースを使用しますが、1行あたり最大79文字を使用するようにしていますが、いつかは不可能です。以前は「importsys、os」のようなインポートも使用していました。一般的に、私はPEP8に固執しようとします。
編集:また使用:
def foobar():
"""
foobar
"""
ドキュメント用
小さなスクリプトを書いているときは、2つのスペースを使用することがよくあります。
Docstringsには常に同じパターンを使用します。
def function():
"""
Even if it's a single line.
"""
python-mode.el、 https://launchpad.net/python-mode
一方、スタイルのカスタマイズが可能です。
M-xカスタマイズ変数RETpy-docstring-style RET
デフォルト値はpep-257-nnです
実装されているスタイルは、Django、ONETWO、PEP-257、PEP-257-NN、SYMMETRIC、およびNILです。
NILの値は引用符の位置を気にせず、docstringを通常の文字列として扱います。他の値は、次のdocstringスタイルのいずれかになります。
Django:
"""
Process foo, return bar.
"""
"""
Process foo, return bar.
If processing fails throw ProcessingError.
"""
ONETWO:
"""Process foo, return bar."""
"""
Process foo, return bar.
If processing fails throw ProcessingError.
"""
PEP-257:
"""Process foo, return bar."""
"""Process foo, return bar.
If processing fails throw ProcessingError.
"""
PEP-257-NN:
"""Process foo, return bar."""
"""Process foo, return bar.
If processing fails throw ProcessingError.
"""
対称:
"""Process foo, return bar."""
"""
Process foo, return bar.
If processing fails throw ProcessingError.
"""
私はpylintを使用しています http://pypi.python.org/pypi/pylint 、それはあなたとあなたのコードにアクセスする他の開発者のためにあなたのコードをきれいにそして読みやすく保つことを試みる優れたツールです。
あなたが言ったすべてのトピックを網羅しているわけではありませんが、それは非常に役に立ちます。
次のようなレポートを作成できます。
carlos@debian:~/src/fcl/cltools$ pylint numbertoletters.py
No config file found, using default configuration
************* Module numbertoletters
C: 1: Missing docstring
C: 56:es_numero: Missing docstring
C: 56:es_numero: Invalid name "s" (should match [a-z_][a-z0-9_]{2,30}$)
C: 56:es_numero: Invalid name "s" (should match [a-z_][a-z0-9_]{2,30}$)
C: 69:convertnumbertoletters: Empty docstring
C: 90:convertnumbertoletters: Operator not preceded by a space
numero='%(numero)09d' % {'numero' : int(parte_entera)}
^
C: 92:convertnumbertoletters: Comma not followed by a space
for i in [0,3,6]:
^^
W: 69:convertnumbertoletters: Unused argument 'languaje'
C:108:unidades: Empty docstring
C:108:unidades: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:108:unidades: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:112:unidades: Invalid name "u" (should match [a-z_][a-z0-9_]{2,30}$)
C:118:teens: Empty docstring
C:118:teens: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:118:teens: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:122:teens: Invalid name "t" (should match [a-z_][a-z0-9_]{2,30}$)
C:127:tens: Empty docstring
C:127:tens: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:127:tens: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:131:tens: Invalid name "t" (should match [a-z_][a-z0-9_]{2,30}$)
C:137:tercia: Empty docstring
C:141:tercia: Operator not preceded by a space
numero='%(numero)03d' % {'numero' : int(num)}
^
C:143:tercia: Invalid name "a" (should match [a-z_][a-z0-9_]{2,30}$)
C:144:tercia: Invalid name "b" (should match [a-z_][a-z0-9_]{2,30}$)
C:145:tercia: Invalid name "c" (should match [a-z_][a-z0-9_]{2,30}$)
C:163:tercia: Operator not followed by a space
resultado ='veinti '+unidades(c)
^
C:165:tercia: Operator not followed by a space
Elif b >=3 and b <= 9:
^^
C:178:tercia: Operator not followed by a space
resultado ='ciento '+unidades(c)
^
C:192:tercia: Operator not followed by a space
resultado ='ciento veinti '+unidades(c)
^
C:204:tercia: Operator not preceded by a space
prefix='quinientos '
^
C:206:tercia: Operator not preceded by a space
prefix='setecientos '
^
C:208:tercia: Operator not preceded by a space
prefix='novecientos '
^
C:210:tercia: Operator not preceded by a space
prefix=unidades(a)+'cientos '
^
R:137:tercia: Too many return statements (23/6)
R:137:tercia: Too many branches (41/12)
R:137:tercia: Too many statements (73/50)
Report
======
141 statements analysed.
Raw metrics
-----------
+----------+-------+------+---------+-----------+
|type |number |% |previous |difference |
+==========+=======+======+=========+===========+
|code |144 |68.25 |NC |NC |
+----------+-------+------+---------+-----------+
|docstring |5 |2.37 |NC |NC |
+----------+-------+------+---------+-----------+
|comment |57 |27.01 |NC |NC |
+----------+-------+------+---------+-----------+
|empty |5 |2.37 |NC |NC |
+----------+-------+------+---------+-----------+
Statistics by type
------------------
+---------+-------+-----------+-----------+------------+---------+
|type |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module |1 |NC |NC |0.00 |0.00 |
+---------+-------+-----------+-----------+------------+---------+
|class |0 |NC |NC |0 |0 |
+---------+-------+-----------+-----------+------------+---------+
|method |0 |NC |NC |0 |0 |
+---------+-------+-----------+-----------+------------+---------+
|function |6 |NC |NC |0.00 |0.00 |
+---------+-------+-----------+-----------+------------+---------+
Duplication
-----------
+-------------------------+------+---------+-----------+
| |now |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines |0 |NC |NC |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |NC |NC |
+-------------------------+------+---------+-----------+
Messages by category
--------------------
+-----------+-------+---------+-----------+
|type |number |previous |difference |
+===========+=======+=========+===========+
|convention |32 |NC |NC |
+-----------+-------+---------+-----------+
|refactor |3 |NC |NC |
+-----------+-------+---------+-----------+
|warning |1 |NC |NC |
+-----------+-------+---------+-----------+
|error |0 |NC |NC |
+-----------+-------+---------+-----------+
Messages
--------
+-----------+------------+
|message id |occurrences |
+===========+============+
|C0103 |14 |
+-----------+------------+
|C0322 |6 |
+-----------+------------+
|C0112 |5 |
+-----------+------------+
|C0323 |4 |
+-----------+------------+
|C0111 |2 |
+-----------+------------+
|W0613 |1 |
+-----------+------------+
|R0915 |1 |
+-----------+------------+
|R0912 |1 |
+-----------+------------+
|R0911 |1 |
+-----------+------------+
|C0324 |1 |
+-----------+------------+
Global evaluation
-----------------
Your code has been rated at 7.45/10
I hope it helps.
特に開発者のコミュニティでは、pylintを使用してコードを評価し、標準的なプログラミング方法を維持することを強くお勧めします。 =)
お役に立てば幸いです。