Why is the use of len(SEQUENCE) in condition values considered incorrect by Pylint?

后端 未结 4 1882
独厮守ぢ
独厮守ぢ 2021-01-30 08:08

Considering this code snippet:

from os import walk

files = []
for (dirpath, _, filenames) in walk(mydir):
    # More code that modifies files
if len(files) == 0:         


        
相关标签:
4条回答
  • 2021-01-30 08:10

    When is the use of len(SEQ) as a condition value problematic? What major situations is Pylint attempting to avoid with C1801?

    It’s not really problematic to use len(SEQUENCE) – though it may not be as efficient (see chepner’s comment). Regardless, Pylint checks code for compliance with the PEP 8 style guide which states that

    For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

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

    As an occasional Python programmer, who flits between languages, I’d consider the len(SEQUENCE) construct to be more readable and explicit (“Explicit is better then implicit”). However, using the fact that an empty sequence evaluates to False in a Boolean context is considered more “Pythonic”.

    0 讨论(0)
  • 2021-01-30 08:20

    Note that the use of len(seq) is in fact required (instead of just checking the bool value of seq) when using NumPy arrays.

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

    results in an exception: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

    And hence for code that uses both Python lists and NumPy arrays, the C1801 message is less than helpful.

    0 讨论(0)
  • 2021-01-30 08:22

    This was a issue in Pylint, and it no longer considers len(x) == 0 as incorrect.

    You should not use a bare len(x) as a condition. Comparing len(x) against an explicit value, such as if len(x) == 0 of if len(x) > 0 is totally fine and not prohibited by PEP 8.

    From PEP 8:

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

    Note that explicitly testing for the length is not prohibited. The Zen of Python states:

    Explicit is better than implicit.

    In the choice between if not seq and if not len(seq), both are implicit, but the behaviour is different. But if len(seq) == 0 or if len(seq) > 0 are explicit comparisons and are in many contexts the correct behaviour.

    In Pylint, PR 2815 has fixed this bug, first reported as issue 2684. It will continue to complain about if len(seq), but it will no longer complain about if len(seq) > 0. The PR was merged 2019-03-19, so if you are using Pylint 2.4 (released 2019-09-14) you should not see this problem.

    0 讨论(0)
  • 2021-01-30 08:34

    Pylint was failing for my code and research led me to this post:

    ../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)
    

    This was my code before:

    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)))
    

    This was after my code fix. By using the int() attribute, I seem to have satisfied the Pep8/Pylint and doesn't seem to have a negative impact on my code:

    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)))
    

    My Fix

    By adding .__trunc__() to the sequence it seems to have settled the need.

    I do not see a difference in the behaviour, but if anyone knows specifics that I am missing, please let me know.

    0 讨论(0)
提交回复
热议问题