我喜欢 Python 3.6 中的 typing.NamedTuple
。但通常情况下,namedtuple
包含一个不可哈希的属性,并且我想将其用作 dict
键或 set
成员。如果 namedtuple
类使用对象标识(id()
作为 __eq__
和 __hash__
) 是有意义的,那么将这些方法添加到类中即可。
然而,现在我的代码中出现了这种模式,我想摆脱繁琐的 __eq__
和 __hash__
方法定义。我知道 namedtuple
并不是常规类,我一直无法搞清楚如何解决这个问题。
以下是我尝试过的方法:
from typing import NamedTuple
class ObjectIdentityMixin:
def __eq__(self, other):
return self is other
def __hash__(self):
return id(self)
class TestMixinFirst(ObjectIdentityMixin, NamedTuple):
a: int
print(TestMixinFirst(1) == TestMixinFirst(1)) # Prints True, so not using my __eq__
class TestMixinSecond(NamedTuple, ObjectIdentityMixin):
b: int
print(TestMixinSecond(2) == TestMixinSecond(2)) # Prints True as well
class ObjectIdentityNamedTuple(NamedTuple):
def __eq__(self, other):
return self is other
def __hash__(self):
return id(self)
class TestSuperclass(ObjectIdentityNamedTuple):
c: int
TestSuperclass(3)
"""
Traceback (most recent call last):
File "test.py", line 30, in <module>
TestSuperclass(3)
TypeError: __new__() takes 1 positional argument but 2 were given
"""
有没有一种方法,可以让我不必在每个需要“对象标识”(object identity)的NamedTuple
中重复这些方法?
__init__
。我尝试添加__new__
,但是NamedTuple
不允许这样做。 - Damon MariaNamedTuple
,并允许你重写__eq__
。只需用dataclasses.dataclass
装饰类即可。 - pylang