你无法做到这一点:
y = MyClass()
y = 3
y = 5
y.previous_value() # will yield 3
Python 中的赋值将名称重新绑定到另一个对象。当您执行y = 3 时,y 现在是整数 3 的名称,而不是 MyClass 的实例。这种行为根本不依赖于旧的 RHS,并且如果没有 deep 魔法(您可以可能使用上下文管理器做一些事情),它就无法被它拦截。 y 曾经引用的MyClass 的实例不知道 y 不再引用它(或者它一开始就这样做了);即使这样做了,y.previous_value() 也会调用 int 上的方法,而不是 MyClass 实例上的方法。
你能做的最接近的就是玩__setitem__。这是当你做这样的事情时 Python 调用的钩子:
x = [1, 2, 3]
x[2] = 5
第二行转换为x.__setitem__(2, 5)。使用它,您可以玩这样的有趣游戏:
class MyClass:
def __init__(self):
self.values = []
def __setitem__(self, item, value):
self.value.append(value)
def previousvalue(self):
return self.values[-2]
def __str__(self):
return str(self.values[-1])
x = MyClass()
x[:] = 5
x[:] = 6
print(x.previousvalue())
请注意,您需要[] 来触发__setitem__,并且它需要有一个值 - 这可以是任何对象,因为它被忽略了,所以我使用一个空切片。您需要跳过这样的句法障碍这一事实应该是一个重要指标,表明您应该重新考虑为什么要这样做 - 几乎可以肯定有更好的方法来实现您的目标。