如何为namedtuple的子类提供额外的初始化?(How to provide additional initialization for a subclass of namedtuple?)

编程入门 行业动态 更新时间:2024-10-22 04:46:26
如何为namedtuple的子类提供额外的初始化?(How to provide additional initialization for a subclass of namedtuple?)

假设我有一个namedtuple这样的:

EdgeBase = namedtuple("EdgeBase", "left, right")

我想为此实现一个自定义哈希函数,所以我创建了以下子类:

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中的子类化和初始化,特别是与元组。 这个解决方案有什么缺陷吗? 有没有推荐的方法如何做到这一点? 好吗 提前致谢。

Suppose I have a namedtuple like this:

EdgeBase = namedtuple("EdgeBase", "left, right")

I want to implement a custom hash-function for this, so I create the following subclass:

class Edge(EdgeBase): def __hash__(self): return hash(self.left) * hash(self.right)

Since the object is immutable, I want the hash-value to be calculated only once, so I do this:

class Edge(EdgeBase): def __init__(self, left, right): self._hash = hash(self.left) * hash(self.right) def __hash__(self): return self._hash

This appears to be working, but I am really not sure about subclassing and initialization in Python, especially with tuples. Are there any pitfalls to this solution? Is there a recommended way how to do this? Is it fine? Thanks in advance.

最满意答案

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__中创建,然后返回给用户,而不是在__init__填充数据。

由于__new__因为历史/奇怪的原因隐含地是一个staticmethod方法,所以cls必须被传递给__new__的super调用两次。

edit for 2017: turns out namedtuple isn't a great idea. attrs is the modern alternative.

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__ is what you want to call here because tuples are immutable. Immutable objects are created in __new__ and then returned to the user, instead of being populated with data in __init__.

cls has to be passed twice to the super call on __new__ because __new__ is, for historical/odd reasons implicitly a staticmethod.

更多推荐

本文发布于:2023-04-29 09:58:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1335926.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:子类   初始化   何为   namedtuple   subclass

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!