在Python中自定义不可变类型

时间:2015-04-20 15:01:00

标签: python immutability delegation

让我们说我想要一个带有2个元素的自定义frozenset,迭代,散列,比较,并具有各种其他不错的操作作为冻结集,但打印方式不同。

>>> p = edge(5, 7)
>>> p == edge(7, 5)
True
>>> p
edge(5, 7)

我可以继承,或者我可以委托,但在任何情况下我都得不到我想要的东西。

如果我按字面继承,似乎无法编写__init__,因为我的父母是不可变的。我可以写一下:

class edge:
    def __new__(cls, a, b):
        return frozenset({a, b})

然后我得到了一个合适的冷冻集,无法自定义__repr__,这就是我想要做的。我不能让super()以任何好的方式在这里工作。

如果我委托,我可以覆盖__getattr____getattribute__,但是当例如__iter__被寻求时,它们都无法正常工作。我想这里的特殊方法太特别了。我目前唯一的解决方案是手动委派我能想到的每一种特殊方法,但肯定必须有更好的方法。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

愚蠢的我。它现在有效。如果有人想知道怎么做,请点击这里:

class pair(frozenset):
    def __new__(cls, a, b):
        return super().__new__(cls, {a, b})
    def __repr__(self):
        a, b = sorted(self)
        return "{} & {}".format(a, b)

错误在于我调用了super().__new__({a, b}),认为在没有参数的情况下调用时,它会像cls一样变换self。当然,__new__是隐式的类方法并没有帮助。 : - )