簡體   English   中英

如果`__add__`引發`NotImplementedError`,是否會調用`__radd__`?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM