在Python中,运算符重载是通过在类中定义特殊方法来实现的。例如,要使用+
运算符,请定义__add__
方法。对于不同的运营商,还有许多其他特殊方法。除此之外,所有这些特殊运算符都来自object
类,它是每个其他类的基类。这意味着每个类都会继承特殊方法,如__add__
,__ge__
,__le__
等等。
现在考虑以下代码。
class test_class:
def ring(self):
print("ring")
obj = test_class()
print(obj.__ge__)
输出:
<method-wrapper '__ge__' of test_class object at 0x0000000002247EF0>
但是当我尝试使用__add__
对象访问obj
时,它会出现以下错误:
AttributeError: 'test_class' object has no attribute '__add__'
为什么?这是否意味着__add__
方法不会继承object
类?到底发生了什么?
答案 0 :(得分:0)
__add__
函数不是object
的属性。它是operator模块中的一个函数。您可以通过在类中实现这些方法的自己版本来提供自己的实现。
文档here中也对此进行了解释。
观察:
>>> class Foo:
... def __add__(self, x):
... print("I took over the add with {}".format(x))
...
>>>
>>>
>>> f = Foo()
>>> f + 100
I took over the add with 100
>>>
此外,即使您查看object
提供给您的内容,您也会看到:
>>> dir(object)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>>
您要覆盖的__add__
没有实现。这些运算符是可覆盖的,方法是在您的班级中自己声明它们。
提供一些上下文,围绕为什么像__eq__
(和其他比较运算符)运算符这样的运算符可能被实现为对象的一部分而不是__add__
作为示例,是因为,根据文档(here),这些相等运算符是富比较方法,它们提供了自己的实现基础对象。如果你看一下object
类的实现,你会看到docstring提到当你将这些操作符实际用于实例对象时将返回的内容:
def __ge__(self, *args, **kwargs): # real signature unknown
""" Return self>=value. """
pass
例如,您可以看到它提到当您尝试执行“&gt;”时对于从对象继承的实例,他们将使用那个实现。