【问题标题】:How to check if len is valid如何检查 len 是否有效
【发布时间】:2020-09-24 04:48:13
【问题描述】:

我有一个函数

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

如果我打电话

foo(42)

抛出异常

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

如何检查输入的值是否可以与 len() 一起使用?

【问题讨论】:

    标签: python


    【解决方案1】:

    你可以这样做:

    if hasattr(bar, '__len__'):
        pass
    

    或者,您可以捕获 TypeError。

    【讨论】:

    • 不需要__len__ in dir(bar)吗?无论哪种方式,如果您采用这种方法,使用hasattr 会更好
    • 即使一个对象有__len__属性,也并不意味着它是有效的(或者OP应该定义什么是有效)。例如,一个类可以定义一个返回str__len__ 函数,它会通过hasattr 测试,但当您对其调用len() 时仍会抛出TypeError 异常。这正是 异常处理 的目的,惩罚他们给我肮脏的输入。
    【解决方案2】:

    可以测试对象是否为Sized

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

    如果Sized 的所有抽象方法都实现了,则isinstance() 测试为真;在这种情况下,这只是__len__

    就我个人而言,我只是捕获异常:

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

    【讨论】:

    • 应该从 collections.abc 导入 Sizedcollections.Sized 和其他自 Python 3.3 起已弃用,并计划在 3.9 中停止工作)
    【解决方案3】:

    由于len() calls __len__() magic method 在后台,您可以检查对象是否在hasattr() 的帮助下定义了__len__ 方法:

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

    【讨论】:

      【解决方案4】:

      您可以使用tryexcept 来获得最佳效果:

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

      【讨论】:

      • 作为一般规则,这可以说是最 Pythonic、鸭式的方法。它不适用于某些用例,例如列表或字典理解。
      猜你喜欢
      • 2010-12-20
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 2021-11-30
      • 2013-08-08
      相关资源
      最近更新 更多