[英]dataclass hash() of field with type annotation and default value = None is always nondeterministic
[英]Pythonic way to check if a dataclass field has a default value
我最近一直在使用 python 3.7,并且正在寻找利用新数据类的方法。 基本上我有一个方法可以遍历数据类字段并检查它们是否具有默认值:
from dataclasses import fields, MISSING
@classmethod
def from_json(cls)
datacls_fields = fields(cls)
for field in datacls_fields:
if (field.default != MISSING):
#...
但是在官方文档中,它说:
MISSING 值是一个哨兵对象,用于检测是否提供了 default 和 default_factory 参数。 使用此标记是因为 None 是默认值的有效值。 任何代码都不应直接使用 MISSING 值。
有人知道更好/更pythonic的方法吗?
这是定义MISSING
在Python源代码dataclasses.py
:
# A sentinel object to detect if a parameter is supplied or not. Use
# a class to give it a better repr.
class _MISSING_TYPE:
pass
MISSING = _MISSING_TYPE()
定义很清楚,它的用例只是检查是否提供了参数,并区分None
和未提供的值:
def my_func(a=MISSING):
if a is not MISSING:
# a value has been supplied, whatever his value
所以在你的代码中使用它进行值比较是完全可以的。 通过告诉No code should直接使用 MISSING 值,他们只是警告我们这个变量没有特定用途(用于比较的其他用途)并且不应在代码中使用以避免意外行为。
您应该更新您的代码以使用更 Pythonic 的语法is not MISSING
:
from dataclasses import fields, MISSING
@classmethod
def from_json(cls)
datacls_fields = fields(cls)
for field in datacls_fields:
if field.default is not MISSING:
我认为 pythonic 解决方案依赖于使用神奇的__dict__
(文档:https ://docs.python.org/3/library/stdtypes.html#object.__dict__ )。
class Foo:
def __init__(self, a=1, b=2, c=3):
self.a = a
self.b = b
self.c = c
x = Foo()
y = Foo(a=5)
print(x.__dict__ == Foo().__dict__) # True
print(y.__dict__ == Foo().__dict__) # False
基本上,当在对象实例上使用时,它返回一个字段值对(键值)的字典。
为了检查这些是否是默认值,我只是将给定实例上的这个字典与在默认无名对象上创建的相同字典进行比较。
代码可能更具解释性。
PS这是所有字段是否都有默认值的答案。 如果您需要确切哪些字段没有默认值的信息,这是我提出的解决方案(基于与上述相同的逻辑,但不是比较字典的相等性,而是找出它们之间的差异):
# Need the actual fields back?
x_dict = x.__dict__
y_dict = y.__dict__
default = Foo().__dict__
print(dict(set(x_dict.items()) - set(default.items())))
print(dict(set(y_dict.items()) - set(default.items())))
使用此代码时的输出:
{}
{'a': 5}
请参阅如何在 Python 中获取两个字典之间的差异? 有关如何查找两个字典之间差异的更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.