web-dev-qa-db-ja.com

Pylintでは、条件値でのlen(SEQUENCE)の使用が誤っていると考えられるのはなぜですか?

このコードスニペットを検討する:

from os import walk

files = []
for (dirpath, _, filenames) in walk(mydir):
    # more code that modifies files
if len(files) == 0: # <-- C1801
    return None

If文の行について、このメッセージを載せてPylintから警告を受けました。

[pylint] C1801:len(SEQUENCE)を条件値として使わない

一見したところ、規則C1801は私にはそれほど合理的に思えませんでした、そして参照ガイドの 定義はこれが問題である理由を説明していません 。実のところ、それはそれを誤用と呼んでいます。

len-as-condition(C1801) 条件値としてlen(SEQUENCE)を使用しないでください)Pylintが条件内でlen(sequence)の誤った使用を検出したときに使用されます。

私の検索の試みも私にもっと深い説明を提供することに失敗しました。シーケンスの長さプロパティが遅延評価され、__len__が副作用を持つようにプログラムできることを私は理解していますが、それだけではPylintがそのような使用を正しくないと呼ぶには十分に問題があるかどうか疑問です。したがって、単純にルールを無視するようにプロジェクトを構成する前に、私は自分の推論で何かが足りないかどうかを知りたいと思います。

条件値としてのlen(SEQ)の使用が問題となるのはいつですか? PylintがC1801で避けようとしている主な状況は何ですか?

165
E_net4

条件値としてのlen(SEQ)の使用が問題となるのはいつですか? PylintがC1801で避けようとしている主な状況は何ですか?

len(SEQUENCE)を使うのは 本当に 問題ではありません - 効率的ではないかもしれませんが( chepnerのコメント を参照)。とにかく、Pylintは PEP 8スタイルガイド に準拠しているかどうかコードをチェックします。

シーケンス(文字列、リスト、タプル)の場合、空のシーケンスはfalseであるという事実を使用します。

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):

ときどきPythonプログラマーとして、言語間を飛び交う私は、len(SEQUENCE)構文をより読みやすく明示的にすることを検討します(「明示的は暗黙的より優れています」)。ただし、空のシーケンスがブール値のコンテキストでFalseに評価されるという事実を使用することは、より「Pythonic」と見なされます。

215

NumPy配列を使うときは、実際には(seqのbool値をチェックする代わりに)len(seq)を使うことが必要です。

a = numpy.array(range(10))
if a:
    print "a is not empty"

valueError:複数の要素を持つ配列の真理値はあいまいです。 a.any()またはa.all()を使用してください。

したがって、PythonリストとNumPy配列の両方を使用するコードの場合、C1801メッセージは役に立ちません。

32
Cameron Hayne
3

Pylintは私のコードに失敗していました、そして研究は私をこの投稿に導きました:

../filename.py:49:11: C1801: Do not use `len(SEQUENCE)` to determine if a sequence is empty (len-as-condition)
../filename.py:49:34: C1801: Do not use `len(SEQUENCE)` to determine if a sequence is empty (len-as-condition)

これは私の前のコードです:

def list_empty_folders(directory):
"""The Module Has Been Build to list empty Mac Folders."""
for (fullpath, dirnames, filenames) in os.walk(directory):
    if len(dirnames) == 0 and len(filenames) == 0:
        print("Exists: {} : Absolute Path: {}".format(
            os.path.exists(fullpath), os.path.abspath(fullpath)))

これは私のコード修正の後でした。 int()attributeを使うことで、Pep8/Pylintを満足しているように見え、私のコードに悪影響を及ぼさないようです。

def list_empty_folders(directory):
"""The Module Has Been Build to list empty Mac Folders."""
for (fullpath, dirnames, filenames) in os.walk(directory):
    if len(dirnames).__trunc__() == 0 and len(filenames).__trunc__() == 0:
        print("Exists: {} : Absolute Path: {}".format(
            os.path.exists(fullpath), os.path.abspath(fullpath)))

私の修正

シーケンスに.__trunc__()を追加することによって、それは必要性を解決したようです。

動作に違いはありませんが、私が見逃していることを誰かが知っている場合はお知らせください。

0
JayRizzo