如何检查 len 是否有效

36

我有一个函数

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

如果我打电话

foo(42)

它会抛出一个异常:

TypeError:'int'类型的对象没有len()

我该如何检查输入的值是否可以用于len()函数?

4个回答

49

你可以做:

if hasattr(bar, '__len__'):
    pass

或者,您可以捕获 TypeError。


2
这不需要写成 __len__ in dir(bar) 吗?无论如何,如果你采用这种方法,使用 hasattr 更好。 - Daenyth
3
即使一个对象具有__len__属性,也不意味着它是有效的(否则操作者应该定义什么是“有效”的)。例如,一个类可以定义一个返回字符串的__len__函数,这将通过hasattr测试,但当您调用len()时仍会引发TypeError异常。这正是异常处理的设计初衷,惩罚它们给我提供脏数据。 - Nier

25

您可以测试对象是否为Sized

import collections.abc

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

isinstance()测试在所有Sized的抽象方法都被实现时返回true, 在这种情况下只需要实现__len__

个人而言,我会选择捕获异常:

try:
    foo(42)
except TypeError:
    pass  # oops, no length

7

由于len()在底层调用了__len__()魔法方法,因此您可以使用hasattr()来检查对象是否定义了__len__方法:

>>> def has_len(obj):
...     return hasattr(obj, '__len__')
... 
>>> has_len([1,2,3])
True
>>> has_len('test')
True
>>> has_len(1)
False

5

为了获得最佳效果,您可以使用 tryexcept 来实现:

def foo(bar):
    #do some things
    try:
        print(len(bar))
    except TypeError:
        print('Input not compatible with len()')

作为一般准则,这可能是最符合Python风格的鸭子类型方法。但对于某些用例,例如列表或字典推导,它并不适用。 - jcomeau_ictx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接