模仿 `len` 和 `bool` 的 Python 行为
Mimicking Python behavior for `len` and `bool`
考虑以下代码:
>>> 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__
函数?
bool()
测试一个对象的真值,所以你要看rules for Truth Value Testing:
By default, an object is considered true unless its class defines either a __bool__()
method that returns False
or a __len__()
method that returns zero, when called with the object.
您只实现了一个故意破坏的 __len__
方法,在调用时引发 TypeError
。但是bool()
将在有实现且没有其他选项可用于确定真值时调用它。
判断真值时,__bool__
is preferred over __len__
:
When this method is not defined, __len__()
is called, if it is defined, and the object is considered true if its result is nonzero.
演示:
>>> 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()
函数实现。 __len__
实现毫无例外地可以引发,让你假装它实际上没有实现,如果它被调用,它引发的任何异常都会传播,因为你通常会想知道实现是否是以某种方式损坏。
考虑以下代码:
>>> 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__
函数?
bool()
测试一个对象的真值,所以你要看rules for Truth Value Testing:
By default, an object is considered true unless its class defines either a
__bool__()
method that returnsFalse
or a__len__()
method that returns zero, when called with the object.
您只实现了一个故意破坏的 __len__
方法,在调用时引发 TypeError
。但是bool()
将在有实现且没有其他选项可用于确定真值时调用它。
判断真值时,__bool__
is preferred over __len__
:
When this method is not defined,
__len__()
is called, if it is defined, and the object is considered true if its result is nonzero.
演示:
>>> 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()
函数实现。 __len__
实现毫无例外地可以引发,让你假装它实际上没有实现,如果它被调用,它引发的任何异常都会传播,因为你通常会想知道实现是否是以某种方式损坏。