假设我有两个Python类,都定义了add和radd运算符重载,并将一个类的一个实例添加到另一个类的另一个实例。选择的实现方式取决于项目的添加顺序(Python首先在LHS上寻找add方法,依此类推)。

我是否可以定义优先选择哪个对象的实现?例如,我希望如果radd的优先级高于LHS的优先级,则在rads上调用radd。

我真的很想对所有重载运算符执行此操作,因此我最终追求的是更通用的解决方案。

[编辑:添加的示例]

例如,我可能有一个自定义数字类型类,并且我可能希望以静默方式将整数转换为我的自定义类型。因此,我需要add和radd(以及所有其他运算符带有'r'表亲的重载)。

接下来,我想要一个通用多项式类,其系数是某种通用数字类型。我也想将事物类型转换为多项式,因此我为其实现了add和radd函数。但是,如果我在左侧添加一个自定义数字,在右侧添加一个多项式,则希望将其类型转换为多项式,而不是Python尝试将其类型转换为自定义数字类型。因此,我希望调用radd而不是add。

最佳答案

如果未使用__radd__运算符在第一个项目上实现__add__,则Python将使用+

foo + bar


将尝试在foo__add__上使用otherbar运算符。如果未实现,它将调用bar__radd__

class Foo(object):
    pass

class Bar(object):
    def __radd__(self, other):
        print('Bar.__radd__ was called!')

>>> foo = Foo()
>>> bar = Bar()
>>> foo + bar
Bar.__radd__ was called!


当Foo具有__add__时,它具有优先权:

class Foo(object):
    def __add__(self, other):
        print('Foo.__add__ was called!')

>>> foo = Foo()
>>> foo + bar
Foo.__add__ was called!


如果两者都实现,则不能强迫Python做任何特殊的事情,优先顺序是预定义的。但是,您可以检查对方的存在:

class Foo(object):
    def __add__(self, other):
        if hasattr(other, '__radd__'):
            return other.__radd__(self)
        else:
            print('Foo.__add__ was called!')

>>> foo = Foo()
>>> foo + bar
Bar.__radd__ was called!

10-07 12:57