2

据我目前的理解,像'+'和'-'这样的算术操作数是一种特殊的方法,属于整数类。它们对我来说似乎不同,因为您不必像这样格式化算术运算:x.__add__(y)但这就是您编写x + y.

我的第一个问题是:到目前为止我是对的吗?

我的第二个问题是:__add__方法中发生了什么?我在任何文档中都找不到这个。我想了解这如何不会导致无限回归,因为我只能将这种方法描绘成这样:

def __add__(a,b):
   return a + b

但是当然,你没有解释'+',这导致了无限回归。

我希望我的问题很清楚,因为我脑子里有点模糊。基本上,我试图很好地理解 Python 的基本原理是什么。(也许是其他语言?)

4

5 回答 5

4

Python 确实将+and-运算符转换为.__add__()调用,但也将__radd__()在第二个操作数上使用方法来进行反向操作。当与标准类型一起使用时,这允许自定义类型挂钩到操作数。

发生的事情x + y是:

  • 如果y是 的子类x,请先尝试y.__radd__(x);这使您可以使用更具体的类覆盖行为。
  • 尝试使用x.__add__(y),如果成功,那就是表达式的结果。如果此调用返回特殊NotImplemented单例,则继续下一步。
  • 尝试使用y.__radd__(x);如果成功,那就是表达式的结果。如果它也返回NotImplemented,则引发TypeError异常,操作符失败。

因为 Python 内置类型是用C 代码实现的,所以实际实现__add__不会触发竞争条件。的 C 代码int.__add__采用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__实现。

于 2014-06-26T13:09:59.110 回答
2

关于__add__(a, b)数字:

我不是 Python 专家,但我的猜测是这随后调用了执行实际计算的本机代码。它是用您正在使用的 Python 实现编写的语言实现的。例如,如果您使用的是 CPython,它会从用 C 编写的 Python 源代码调用(编译的)函数。

于 2014-06-26T13:09:04.087 回答
1

数字类型的__add__方法很可能在本机代码中实现,因此无限递归不太可能发生,因此您的 return a+b 实际上是本机代码调用

于 2014-06-26T13:07:50.853 回答
0

那么+符号是一个运算符,因此它是任何编程语言的基本构建块。Python 和大多数其他 OOP 语言允许您+为自定义类定义运算符。这是通过__add__在新类中定义方法来完成的。

希望这有助于您的理解

于 2014-06-26T13:07:42.440 回答
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

作品你可以假设它不是一路下来的乌龟!

于 2014-06-26T13:16:34.033 回答