如何为namedtuple的子类提供额外的初始化?
假设我有一个像这样的namedtuple
:
EdgeBase = namedtuple("EdgeBase", "left, right")
我想为此实现一个自定义的散列函数,所以我创build了下面的子类:
class Edge(EdgeBase): def __hash__(self): return hash(self.left) * hash(self.right)
由于对象是不可变的,所以我希望哈希值只能计算一次,所以我这样做:
class Edge(EdgeBase): def __init__(self, left, right): self._hash = hash(self.left) * hash(self.right) def __hash__(self): return self._hash
这似乎工作,但我真的不知道在Python的子类化和初始化,特别是与元组。 这个解决scheme有什么缺陷吗? 有一个build议的方式如何做到这一点? 好吗? 提前致谢。
class Edge(EdgeBase): def __new__(cls, left, right): self = super(Edge, cls).__new__(cls, left, right) self._hash = hash(self.left) * hash(self.right) return self def __hash__(self): return self._hash
__new__
是你想在这里调用,因为元组是不可变的。 不可变对象在__new__
中创build,然后返回给用户,而不是在__init__
填充数据。
cls
必须在__new__
上被传递给super
调用两次,因为__new__
由于历史/奇怪的原因隐含地是staticmethod
。
问题中的代码可以从__init__
中的超级调用中受益,以防在多重inheritance情况下被分类,否则是正确的。
class Edge(EdgeBase): def __init__(self, left, right): super(Edge, self).__init__(a, b) self._hash = hash(self.left) * hash(self.right) def __hash__(self): return self._hash
尽pipe元组只是只读的,但它们的子类的元组部分是只读的,其他属性可以像往常一样写,这就允许赋值_hash,而不pipe它是在__init__
还是__new__
。 您可以通过将__slots__
设置为()来使子类完全只读,这有助于节省内存,但是您将无法将其指定给_hash。