Python 数据类生成散列并排除不安全字段
Python dataclass generate hash and exclude unsafe fields
我有这个数据类:
from dataclasses import dataclass, field
from typing import List
@dataclass
class Person:
name: str
dob: str
friends: List['Person'] = field(default_factory=list, init=False)
name
和 dob
是不可变的,而 friends
是可变的。我想生成每个人对象的哈希值。我可以以某种方式指定要包含和排除哪些字段以生成 __hash__
方法吗?在这种情况下,name
和 dob
应该包含在生成哈希中,而 friends
不应该。这是我的尝试,但没有用
@dataclass
class Person:
name: str = field(hash=True)
dob: str = field(hash=True)
friends: List['Person'] = field(default_factory=list, init=False, hash=False)
>>> hash(Person("Mike", "01/01/1900"))
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
hash(Person("Mike", "01/01/1900"))
TypeError: unhashable type: 'Person'
我也找不到将 name
和 dob
设置为冻结的方法。而且我会避免将 unsafe_hash
设置为 True
,只是因为它的声音。有什么建议吗?
此外,我正在做的事情被认为是好的做法吗?如果没有,你能推荐一些替代方案吗?
谢谢
编辑:这只是一个玩具示例,我们可以假设 name 和 dob 字段是唯一的。
编辑:我举了一个例子来证明错误。
只是指出在与__eq__
比较实例时不应考虑friends
字段,并将hash=True
传递给所需字段上的字段实例。
然后,将 unsafe_hash=True
参数传递给 dataclass
装饰器本身 - 它会按您的预期工作(主要是):
在散列的情况下,语言限制是如果一个实例与另一个实例比较相等(__eq__
),则两者的散列也必须相等。这种情况下的含义是,如果 "same" 人的两个实例具有相同的 "name" 和 "dob" 字段,则它们将被视为相等,即使它们具有不同的朋友列表。
除此之外,这应该可行:
from dataclasses import dataclass, field
from typing import List
@dataclass(unsafe_hash=True)
class Person:
name: str = field(hash=True)
dob: str = field(hash=True)
friends: List['Person'] = field(default_factory=list, init=False, compare=False, hash=False)
然后,记得像 "consenting adult" 和 而不是 在任何地方更改 Person 实例的 "name" 和 "dob" 字段,你已经准备好了。
我有这个数据类:
from dataclasses import dataclass, field
from typing import List
@dataclass
class Person:
name: str
dob: str
friends: List['Person'] = field(default_factory=list, init=False)
name
和 dob
是不可变的,而 friends
是可变的。我想生成每个人对象的哈希值。我可以以某种方式指定要包含和排除哪些字段以生成 __hash__
方法吗?在这种情况下,name
和 dob
应该包含在生成哈希中,而 friends
不应该。这是我的尝试,但没有用
@dataclass
class Person:
name: str = field(hash=True)
dob: str = field(hash=True)
friends: List['Person'] = field(default_factory=list, init=False, hash=False)
>>> hash(Person("Mike", "01/01/1900"))
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
hash(Person("Mike", "01/01/1900"))
TypeError: unhashable type: 'Person'
我也找不到将 name
和 dob
设置为冻结的方法。而且我会避免将 unsafe_hash
设置为 True
,只是因为它的声音。有什么建议吗?
此外,我正在做的事情被认为是好的做法吗?如果没有,你能推荐一些替代方案吗?
谢谢
编辑:这只是一个玩具示例,我们可以假设 name 和 dob 字段是唯一的。
编辑:我举了一个例子来证明错误。
只是指出在与__eq__
比较实例时不应考虑friends
字段,并将hash=True
传递给所需字段上的字段实例。
然后,将 unsafe_hash=True
参数传递给 dataclass
装饰器本身 - 它会按您的预期工作(主要是):
在散列的情况下,语言限制是如果一个实例与另一个实例比较相等(__eq__
),则两者的散列也必须相等。这种情况下的含义是,如果 "same" 人的两个实例具有相同的 "name" 和 "dob" 字段,则它们将被视为相等,即使它们具有不同的朋友列表。
除此之外,这应该可行:
from dataclasses import dataclass, field
from typing import List
@dataclass(unsafe_hash=True)
class Person:
name: str = field(hash=True)
dob: str = field(hash=True)
friends: List['Person'] = field(default_factory=list, init=False, compare=False, hash=False)
然后,记得像 "consenting adult" 和 而不是 在任何地方更改 Person 实例的 "name" 和 "dob" 字段,你已经准备好了。