[python] 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) :
Pylint가 조건 내부에서 len (sequence)의 잘못된 사용을 감지 할 때 사용 len(SEQUENCE)되는 조건 값으로 사용 하지 마십시오 .

나의 검색 시도도 나에게 더 깊은 설명을 제공하지 못했습니다. 나는 시퀀스의 길이 속성이 느리게 평가 __len__될 수 있고 부작용을 갖도록 프로그래밍 될 수 있음을 이해하지만 Pylint가 그러한 사용을 잘못 사용하기에 충분히 문제가되는지 여부는 의문의 여지가 있습니다. 따라서 규칙을 무시하도록 프로젝트를 간단하게 구성하기 전에 추론에 뭔가 빠졌는지 여부를 알고 싶습니다.

len(SEQ)조건 값으로 사용하는 것이 언제 문제가됩니까? Pylint가 C1801로 피하려고하는 주요 상황은 무엇입니까?



답변

len(SEQ)조건 값으로 사용하는 것이 언제 문제가됩니까? Pylint가 C1801로 피하려고하는 주요 상황은 무엇입니까?

그것은 아니에요 정말 사용에 문제가 len(SEQUENCE)– 그것은 (참조 효율적으로되지 않을 수 있지만 chepner의 의견을 ). Pylint는 PEP 8 스타일 가이드 를 준수하는지 코드를 확인 합니다.

시퀀스 (문자열, 목록, 튜플)의 경우 빈 시퀀스가 ​​거짓이라는 사실을 사용하십시오.

Yes: if not seq:
     if seq:

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

언어 사이에서 우연히 나오는 가끔 파이썬 프로그래머로서, 나는 len(SEQUENCE)구문을 더 읽기 쉽고 명확하게 생각합니다 ( “명시 적 일수록 암시적일 것”). 그러나 False부울 컨텍스트에서 빈 시퀀스가 ​​평가된다는 사실을 사용하는 것이 “Pythonic”으로 간주됩니다.


답변

NumPy 배열을 사용할 때 실제로 se (의 bool 값을 확인하는 대신) len (seq)을 사용해야합니다.

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

예외 : ValueError : 둘 이상의 요소가있는 배열의 실제 값이 모호합니다. a.any () 또는 a.all ()을 사용하십시오.

따라서 Python 목록과 NumPy 배열을 모두 사용하는 코드의 경우 C1801 메시지가 도움이되지 않습니다.


답변

이것은 pylint의 문제였으며 더 이상 len(x) == 0잘못된 것으로 간주 하지 않습니다.

베어 len(x) 를 조건 으로 사용해서는 안됩니다 . 비교 len(x)와 같은 명시적인 값과 if len(x) == 0의 것은 if len(x) > 0완전히 잘하지 PEP (8)에 의해 금지되어 있습니다.

에서 PEP 8 :

# Correct:
if not seq:
if seq:

# Wrong:
if len(seq):
if not len(seq):

길이명시 적으로 테스트하는 것은 금지되지 않습니다. 파이썬선은 다음과 같이 말합니다.

암시적인 것보다 명시적인 것이 좋습니다.

if not seq및 사이의 선택 if not len(seq)에서 둘 다 암시 적이지만 동작이 다릅니다. 그러나 if len(seq) == 0또는 if len(seq) > 0명백한 비교이며 많은 상황에서 올바른 행동입니다.

pylint에서 PR 2815 는이 버그를 수정했으며 처음에는 이슈 2684 로보고되었습니다 . 그것에 대해 계속 불평 if len(seq)하지만 더 이상 불평하지 않습니다 if len(seq) > 0. PRyl은 2019-03-19에 병합되었으므로 pylint 2.4 (2019-09-14 릴리스)를 사용하는 경우이 문제가 표시되지 않습니다.


답변

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() attributePep8 / 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__()시퀀스에 추가함으로써 필요를 해결 한 것으로 보입니다.

나는 행동에 차이가 보이지 않지만 내가 누락 된 세부 사항을 아는 사람이 있으면 알려주십시오.


답변