gpt4 book ai didi

python - 你能为 Python 中的重载运算符施加对象优先级吗?

转载 作者:太空宇宙 更新时间:2023-11-04 03:48:54 27 4
gpt4 key购买 nike

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

我是否可以定义一个优先级来决定优先使用哪个对象的实现?例如,如果 radd 的优先级高于 LHS,我希望在 RHS 上调用它。

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

[编辑:添加示例]

例如,我可能有一个自定义数字类型类,我可能希望静默地将 int 类型转换为我的自定义类型。因此我需要 add 和 radd(以及所有其他运算符用它们的“r”表亲重载)。

接下来,我想要一个泛型多项式类,其系数是某种泛型数字类型。我还想将内容转换为多项式,因此我为它实现了 add 和 radd 函数。但是,如果我在左侧添加一个自定义数字,在右侧添加一个多项式,我希望它被向上类型转换为多项式,而不是 Python 试图将它向下类型转换> 自定义数字类型。因此,我希望调用 radd 而不是 add。

最佳答案

没有用于定义您所描述的“优先级”的内置机制。您可以做的是在魔术方法中自己实现优先级检查。也就是说,您可以定义该对象的 __add__ 方法,以便它检查另一个对象的“优先级”(无论如何定义),并调用该对象的 __add__(或 __radd__) 如果它的优先级更高。

请注意,如果您只想让 LHS __add__ 延迟到 RHS __radd__,您可以返回 NotImplemented,这实际上会告诉 Python “就好像您刚刚调用的 __add__ 方法不存在一样”。

下面是如何使用魔术方法上的装饰器完成此操作的草图:

def deco(op):
def newOp(self, other):
if other.precedence > self.precedence:
return NotImplemented
return op(self, other)
return newOp

class Thing(object):
precedence = 0

def __init__(self, val):
self.val = val

@deco
def __add__(self, other):
print "Called", self, "__add__"
return self.__class__(self.val + other.val)

def __radd__(self, other):
print "Called", self, "__radd__"
return self.__class__(self.val + other.val)

class Weak(Thing):
precedence = 1

class Strong(Thing):
precedence = 2

这导致总是调用 Strong 版本,而不管操作数的顺序如何,所以它总是返回一个 Strong:

>>> Weak(1) + Strong(1)
Called <__main__.Strong object at 0x01F96BF0> __radd__
<__main__.Strong object at 0x01F96BD0>
>>> Strong(1) + Weak(1)
Called <__main__.Strong object at 0x01F96B90> __add__
<__main__.Strong object at 0x01F96250>

关于python - 你能为 Python 中的重载运算符施加对象优先级吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22289093/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com