[英]is `__radd__` called if `__add__` raises `NotImplementedError`?
假設我們寫了一點 class:
class K:
pass
obj = K()
下面的代碼是...
total = 4 + obj
...與以下基本相同?
import io
try:
total = 4.__add__(obj)
except NotImplementedError:
try:
total = obj.__radd__(4)
except AttributeError:
# type(obj) does not have an `__radd__` method
with io.StringIO() as string_stream:
print(
"unsupported operand type(s) for +:",
repr(type(4).__name__),
"and",
repr(type(obj).__name__),
file=string_stream
) # `repr` puts quotes around the type names
msg = string_stream.getvalue()
raise TypeError(msg) from None
實際上,觸發__radd__()
的行為不是NotImplementedError
,而是稱為NotImplemented
的特殊 object :
>>> help(NotImplemented)
Help on NotImplementedType object:
class NotImplementedType(object)
| Methods defined here:
|
| __reduce__(...)
| Helper for pickle.
|
| __repr__(self, /)
| Return repr(self).
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
NotImplementedError
仍會作為錯誤傳播。 但是,返回NotImplemented
object(而不是引發錯誤)將允許__radd__()
觸發:
>>> class A:
... def __add__(self, other):
... raise NotImplementedError()
...
>>> class B:
... def __add__(self, other):
... print("__add__ was called")
... def __radd__(self, other):
... print("__radd__ was called")
...
>>> class C:
... def __add__(self, other):
... return NotImplemented
...
>>> a, b, c = A(), B(), C()
>>> b + a
__add__ was called
>>> a + b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __add__
NotImplementedError
>>> b + c
__add__ was called
>>> c + b
__radd__ was called
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.