我想为任何数据编写一个通用包装类。我主要是想做一个功能,如果有一段时间没有使用它,它会自动在硬盘上存储数据(类似于自动交换)。在
我已经用python编程多年了,但是我找不到一种“pythonic”的方法来实现这一点。我最终求助于一个脚本,它可以为我编写所有可能的方法,但即使这样也没有成功。看看下面的。在
我甚至不能让这个简单的代码工作——为什么???在
class adder(object):
def __init__(self, value):
self.value = value
def __add__(self, other):
print 'adding'
return self.value.__add__(other)
def __radd__(self, other):
print 'radding'
return self.value.__radd__(other)
a = adder(10)
b = adder(12)
print a + b
输出
^{pr2}$我当然知道我不能使用add和radd函数(只使用+语法)。我这样做是为了看看到底发生了什么:这是结果
class adder2(object):
def __init__(self, value):
self.value = value
def __add__(self, other):
print 'a2'
return self.value + other
def __radd__(self, other):
print 'ra2'
return other + self.value
a = adder(adder2(10))
b = adder(adder2(12))
print a + b
输出:
adding
a2
radding
ra2
22
很明显,它会进入“加法”函数,然后进入第二类的加法函数,然后进入第一类的“radding”函数,最后进入第二类的“radding”函数,到底发生了什么事???而且,当另一个人不这样做的时候,这是有效的——我很困惑。在
另外,如果你知道任何代码已经做到了这一点,请让我知道!在
当您执行
a + b
时,它调用调用self.value.__add__(other)
。由于a.value
为10,因此调用(10).__add__(b)
。由于b
是一个adder
实例,整数10不知道如何将自身添加到b
,因此它返回NotImplemented
。在此阶段不调用b
的__radd__
方法!由于返回self.value.__add__(other)
的结果,__add__
方法也返回NotImplemented。一旦发生这种情况,调用b.__radd__(a)
,并返回NotImplemented
,原因相同——它委托给(12).__radd__(a)
,但失败了。由于两者都返回NotImplemented
,Python认为这些对象不知道如何相互添加,因此会引发错误。在正如您所发现的,解决方案是使用},等等)。当您使用}。当您直接调用
+
,而不是直接调用magic方法。(您不需要为此创建单独的类;只需将adder
类改为调用self.value + other
,而不是{+
时,您将激活Python的内部机制,从而在左操作数上调用__add__
,如果这不起作用,则对右操作数调用{__add__
和__radd__
时,您绕过了这个内部机制,只调用了这两个机制中的一个。这意味着您永远不会到达这样一种状态:两个对象都将自己“还原”为其基础值。相反,您尝试使用左手的__add__
,当它失败时,您不会“退回”到__radd__
-您将从__radd__
重新开始,失去第一部分中所做的“值缩减”。在关键的是}永远不会被调用。在
10 + b
知道如果(10).__add__(b)
失败,就调用b.__radd__(10)
,但是如果直接调用(10).__add__(b)
,它就不知道__radd__
,所以{在Python(docs)中模拟数值类型
计算表达式}实现;如果没有实现或返回{},则不能添加它们。在
a + b
时,首先检查a
,然后执行__add__
实现;如果有,则执行a.__add__(b)
。如果没有,或者运行a.__add__(b)
返回特殊值NotImplemented
,则检查b
是否有{你的代码怎么了
提醒我们的目标:
^{pr2}$print a + b
可以描述为:怎么办
我想你是在尝试创建一个可以添加到数字或其类型的其他对象的类型。如果是,你想
相当于没有
+
的版本:相关问题 更多 >
编程相关推荐