36

I have a function

def foo(bar):
    #do some things
    len(bar)

If I call

foo(42)

it throws an exception of

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

How do I check if the entered value can be used with len()?

DeadEli
  • 983
  • 2
  • 13
  • 28

4 Answers4

49

You can do:

if hasattr(bar, '__len__'):
    pass

Alternatively, you can catch the TypeError.

Nathaniel Flath
  • 15,477
  • 19
  • 69
  • 94
  • 2
    Wouldn't this need to be `__len__ in dir(bar)`? Either way, using `hasattr` is better if you go with this approach – Daenyth May 09 '14 at 14:54
  • 3
    Even an object has `__len__` attribute, it doesn't mean it's valid (or OP should define what is **valid**). For example, a class can define a `__len__` function which returns a `str`, and it will pass the `hasattr` test but still throw the `TypeError` exception when you call `len()` on it. This is exactly what **exception handling** is designed for, punish them for giving me dirty input. – Nier Apr 08 '16 at 03:45
25

You can test if the object is Sized:

import collections.abc

if isinstance(bar, collections.abc.Sized):

The isinstance() test is true if all abstract methods of Sized are implemented; in this case that's just __len__.

Personally, I'd just catch the exception instead:

try:
    foo(42)
except TypeError:
    pass  # oops, no length
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
7

Since len() calls __len__() magic method under the hood, you can check if an object has __len__ method defined with the help of hasattr():

>>> def has_len(obj):
...     return hasattr(obj, '__len__')
... 
>>> has_len([1,2,3])
True
>>> has_len('test')
True
>>> has_len(1)
False
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
5

You can do it using try and except for best results:

def foo(bar):
    #do some things
    try:
        print(len(bar))
    except TypeError:
        print('Input not compatible with len()')
sshashank124
  • 31,495
  • 9
  • 67
  • 76
  • As a general rule, that's arguably the most Pythonic, duck-typing approach. It doesn't work for some use cases, e.g. list or dict comprehensions. – jcomeau_ictx Feb 17 '21 at 03:39