Is there any case where len(someObj) does not call someObj's __len__ function?

前端 未结 5 1476
挽巷
挽巷 2020-12-06 02:45

Is there any case where len(someObj) does not call someObj\'s __len__ function?

I recently replaced the former with the latter in a (sucess

相关标签:
5条回答
  • 2020-12-06 03:03

    What kind of speedup did you see? I cannot imagine it was noticeable was it?

    From http://mail.python.org/pipermail/python-list/2002-May/147079.html

    in certain situations there is no difference, but using len() is preferred for a couple reasons.

    first, it's not recommended to go calling the __methods__ yourself, they are meant to be used by other parts of python.

    len() will work on any type of sequence object (lists, tuples, and all). __len__ will only work on class instances with a __len__ method.

    len() will return a more appropriate exception on objects without length.

    0 讨论(0)
  • 2020-12-06 03:12

    If __len__ returns a length over sys.maxsize, len() will raise an exception. This isn't true of calling __len__ directly. (In fact you could return any object from __len__ which won't be caught unless it goes through len().)

    0 讨论(0)
  • According to Mark Pilgrim, it looks like no. len(someObj) is the same as someObj.__len__();

    Cheers!

    0 讨论(0)
  • 2020-12-06 03:14

    I think the answer is that it will always work -- according to the Python docs:

    __len__(self):
    

    Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn't define a __nonzero__() method and whose __len__() method returns zero is considered to be false in a Boolean context.

    0 讨论(0)
  • 2020-12-06 03:19

    There are cases where len(someObj) is not the same as someObj.__len__() since len() validates __len__()'s return value. Here are the possible errors in Python 3.6.9:

    • Too small, i.e. less than 0

      ValueError: __len__() should return >= 0
      
    • Too big, i.e. greater than sys.maxsize (CPython-specific, per the docs)

      OverflowError: cannot fit 'int' into an index-sized integer
      
    • An invalid type, e.g float

      TypeError: 'float' object cannot be interpreted as an integer
      
    • Missing, e.g. len(object)

      TypeError: object of type 'type' has no len()
      

      I mention this because object.__len__() raises a different exception, AttributeError.

    It's also worth noting that range(sys.maxsize+1) is valid, but its __len__() raises an exception:

    OverflowError: Python int too large to convert to C ssize_t
    
    0 讨论(0)
提交回复
热议问题