【问题标题】:How to design a python class which will behave like root classes如何设计一个行为类似于根类的python类
【发布时间】:2014-03-26 07:42:10
【问题描述】:

编辑:

如回复中所述,此问题的搜索关键字是 “python中的赋值运算符重载”。

我想构建一个行为类似于整数或字符串类行为的类。类似的东西:

x = "hello"
x.upper() # says "HELLO"


y = MyClass()
y = 3
y = 5
print(y) # will print 5
y.previous_value() # will yield 3

我怎样才能建立一个这样的类?

编辑:

目前最接近的 hack 是:https://stackoverflow.com/a/6012807/1952991

【问题讨论】:

标签: python class operator-overloading


【解决方案1】:

你无法做到这一点:

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__,并且它需要有一个值 - 这可以是任何对象,因为它被忽略了,所以我使用一个空切片。您需要跳过这样的句法障碍这一事实应该是一个重要指标,表明您应该重新考虑为什么要这样做 - 几乎可以肯定有更好的方法来实现您的目标。

【讨论】:

    猜你喜欢
    • 2011-04-30
    • 2011-05-31
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 2011-05-11
    相关资源
    最近更新 更多