如何使python数据类可哈希化? [英] How can I make a python dataclass hashable?

查看:338
本文介绍了如何使python数据类可哈希化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说a我在python3中有一个数据类.我希望能够对这些对象进行哈希处理和排序.

Say a I have a dataclass in python3. I want to be able to hash and order these objects.

我只希望它们按ID排序/散列.

I only want them ordered/hashed on id.

我在文档中看到我可以只实现__hash__以及所有其他功能,但是我想让datacalses为我做这些工作,因为它们旨在解决这个问题.

I see in the docs that I can just implement __hash__ and all that but I'd like to get datacalsses to do the work for me because they are intended to handle this.

from dataclasses import dataclass, field

@dataclass(eq=True, order=True)
class Category:
    id: str = field(compare=True)
    name: str = field(default="set this in post_init", compare=False)

a = sorted(list(set([ Category(id='x'), Category(id='y')])))

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'Category'

推荐答案

来自文档:

以下是管理__hash__()方法的隐式创建的规则:

Here are the rules governing implicit creation of a __hash__() method:

[...]

如果eqfrozen都为true,则默认情况下dataclass()将 为您生成一个__hash__()方法.如果eq为true并且frozen 为false时,__hash__()将设置为None,将其标记为不可散列 (它是可变的,因为它是可变的).如果eq为false,则__hash__() 将保持不变,这意味着__hash__()方法 将使用超类(如果超类是对象,则意味着它 将回退到基于ID的哈希).

If eq and frozen are both true, by default dataclass() will generate a __hash__() method for you. If eq is true and frozen is false, __hash__() will be set to None, marking it unhashable (which it is, since it is mutable). If eq is false, __hash__() will be left untouched meaning the __hash__() method of the superclass will be used (if the superclass is object, this means it will fall back to id-based hashing).

由于您设置了eq=True并将frozen保留为默认值(False),因此您的数据类不可散列.

Since you set eq=True and left frozen at the default (False), your dataclass is unhashable.

您有3个选择:

  • 设置frozen=True(除了eq=True之外),这将使您的类不可变且可哈希化.
  • Set unsafe_hash=True,它将创建一个__hash__方法,但使您的类保持可变状态,因此,如果在存储在dict或set中的同时修改了您的类的实例,则可能会出现问题:

  • Set frozen=True (in addition to eq=True), which will make your class immutable and hashable.
  • Set unsafe_hash=True, which will create a __hash__ method but leave your class mutable, thus risking problems if an instance of your class is modified while stored in a dict or set:

cat = Category('foo', 'bar')
categories = {cat}
cat.id = 'baz'

print(cat in categories)  # False

  • 手动实现__hash__方法.
  • Manually implement a __hash__ method.
  • 这篇关于如何使python数据类可哈希化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆