任何d的Python通用包装类

2024-10-02 20:39:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我想为任何数据编写一个通用包装类。我主要是想做一个功能,如果有一段时间没有使用它,它会自动在硬盘上存储数据(类似于自动交换)。在

我已经用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}$

我当然知道我不能使用addradd函数(只使用+语法)。我这样做是为了看看到底发生了什么:这是结果

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”函数,到底发生了什么事???而且,当另一个人不这样做的时候,这是有效的——我很困惑。在

另外,如果你知道任何代码已经做到了这一点,请让我知道!在


Tags: 数据方法函数代码selfaddreturnvalue
2条回答

当您执行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是否有{}实现;如果没有实现或返回{},则不能添加它们。在

你的代码怎么了

提醒我们的目标:

>>> a = adder(adder2(10))
>>> a.value
adder2
>>> a.value.value
10

>>> b = adder(adder2(12))
>>> b.value
adder2
b.value.value
12

print a + b可以描述为:

^{pr2}$

怎么办

我想你是在尝试创建一个可以添加到数字或其类型的其他对象的类型。如果是,你想

class Adder(object):
    def __init__(self, value):
        self.value
    def __add__(self, other):
        return self.value + other
    def __radd__(self, other):
        return self.value + other

相当于没有+的版本:

class Adder(object):
    def __init__(self, value):
        self.value
    def __add__(self, other):
        r = self.value.__add__(other)
        if r is NotImplemented:
            r = other.__radd__(self.value) # so if other is a adder, use its __radd__ 
        return r                           # since our value's __add__ will return
    __radd__ = __add__

相关问题 更多 >