正如我目前所理解的那样,算术操作数如' +'和' - '是一种特殊的方法,属于整数类。它们似乎与我不同,因为你不必像以下那样格式化算术运算:x.__add__(y)
但这就是你写x + y
时幕后发生的事情。
我的第一个问题是:到目前为止我是对的吗?
我的第二个问题是:__add__
方法会发生什么?我无法在任何文档中找到它。我想了解这不会导致无限回归,因为我只能将此方法描述为:
def __add__(a,b):
return a + b
然而当然,你并没有解释' +'离开,这导致无限回归。
我希望我的问题很明确,因为我的脑子里有点模糊。基本上我试图很好地理解Python的基本原理。 (也许还有其他语言?)
答案 0 :(得分:4)
+
和-
运算符转换为.__add__()
调用,但也会在第二个操作数上使用__radd__()
方法进行反向调用。这允许自定义类型在与标准类型一起使用时挂钩到操作数。
x + y
会发生什么:
y
是x
的子类,请先尝试y.__radd__(x)
;这使您可以使用更具体的类覆盖行为。x.__add__(y)
,如果成功,那就是表达式的结果。如果此调用返回特殊NotImplemented
单例,请继续执行下一步。y.__radd__(x)
;如果成功,那就是表达的结果。如果它也返回NotImplemented
,则引发TypeError
异常,操作员失败。由于Python内置类型是在 C代码中实现的,因此__add__
的实际实现不会触发竞争条件。 int.__add__
的C代码采用 C整数值和C +
运算符,只是将数字加在一起。
在自定义Python对象中,通常表示在添加属性或其他值方面添加:
def __add__(self, other):
if not isinstance(other, type(self)):
return NotImplemented # cannot handle other types
return type(self)(self.foobar + other.foobar + self.summation_margin)
其中属性可能有自己的__add__
实现。
答案 1 :(得分:2)
关于数字的__add__(a, b)
:
我不是Python专家,但我的猜测是,它随后会调用执行实际计算的本机代码。它是用您编写的python实现所使用的语言实现的。例如,如果您使用的是CPython,它将使用C语言编写的Python源代码调用(编译)函数。
答案 2 :(得分:1)
数字类型的__add__
方法很可能在本机代码中实现,因此无限递归不是可能的情况,因此返回a + b实际上是本机代码调用
答案 3 :(得分:0)
+
符号是一个操作符,因此它是任何编程语言的基本构建块。 Python和大多数其他OOP语言允许您做的是为自定义类定义+
运算符。这是通过在新类中定义__add__
方法来完成的。
希望这有助于您理解
答案 4 :(得分:0)
你是对的:
class Test(object):
def __add__(self, other):
return self + other
会导致问题:
>>> a = Test()
>>> b = Test()
>>> a + b
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
a + b
File "<pyshell#27>", line 4, in __add__
return self + other
...
File "<pyshell#27>", line 4, in __add__
return self + other
RuntimeError: maximum recursion depth exceeded
但是,这不是如何实现类添加的。通常,您可以将实例的添加定义为对属性的添加,例如:
class Money(object):
def __init__(self, amount):
self.amount = amount
def __add__(self, other):
return Money(self.amount + other.amount)
在amount
中添加__add__
属性取决于__add__
对amount
类型的实施情况,但是:
>>> 1 + 2
3
工作,你可以假设它不是海龟所有的方式!