模仿`len`和`bool`的Python行为

时间:2019-05-12 13:54:07

标签: python class built-in

考虑以下代码:

>>> class X:
... pass
...
>>> x = X()
>>> len(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'X' has no len()
>>> bool(x)
True

但是,当试图模仿本文__len__时,它是行不通的。

>>> class Y:
...   def __len__(self):
...     raise TypeError
...
>>> y = Y()
>>> len(y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __len__
TypeError
>>> bool(y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __len__
TypeError

有没有办法编写一个__len__函数,就像未实现一样?

1 个答案:

答案 0 :(得分:3)

bool()测试对象的真值,因此您要查看rules for Truth Value Testing

  

默认情况下,除非对象的类定义了__bool__()方法(该方法返回{{1})或False(当与该对象一起调用时返回零),否则认为该对象为真。

您仅实现了一个故意中断的__len__()方法,在调用时会引发__len__。但是TypeError 在有实现的情况下调用它,并且没有其他可用的选项来确定真值。

确定真值时,__bool__ is preferred over __len__

  

未定义此方法时,将调用bool()(如果已定义),并且如果其结果为非零,则认为该对象为true。

演示:

__len__()

请注意,当>>> class Z: ... def __bool__(self): ... return True ... def __len__(self): ... raise TypeError ... >>> len(Z()) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in __len__ TypeError >>> bool(Z()) True 钩子没有实现时,是len()函数实现引发TypeError__len__实现不会引发任何异常,这会让您假装它实际上并未实现,如果调用它,则会传播它引发的任何异常,因为您通常会想知道该实现是否为以某种方式破裂。