提问人:Pastafarianist 提问时间:10/20/2023 更新时间:10/21/2023 访问量:51
具有可选参数但非可选字段类型的 Python 冻结数据类
Python frozen dataclass with an optional parameter but non-optional field type
问:
我有一个这样的数据类:
@dataclasses.dataclass(frozen=True)
class MyClass:
my_field: str
other_field: str
我有一个复杂的函数来计算默认值,这取决于:my_field
other_field
def get_default_value_for_my_field(other_field: str) -> str:
... # lots of code
有没有办法:
- 如果在初始化时没有传递 for 值,则从其结果调用并初始化,否则从传递的值初始化;
get_default_value_for_my_field(other_field)
my_field
my_field
my_field
- 保持冷冻;
MyClass
- 说服有类型而不是
pytype
MyClass.my_field
str
str | None
; - 说服有一个参数
pytype
MyClass.__init__()
my_field: str | None = None
使用数据类,还是我最好切换到普通类?
答:
0赞
Lucas M. Uriarte
10/21/2023
#1
我不认为所有这些条件都可以使用 daclasses。我曾经遇到过同样的问题,并找到了一个实际上可以很容易地解决上述所有问题的软件包。该包是 call attrs,如果您使用 dataclasses,您可以看到它执行相同的操作,但添加了一些非常酷的功能,而不会干扰类或类似于 pydantic 所做的。 它的工作方式与数据类相同,您可能需要更改很少的代码才能从 dataclass 移动到 attrs,但它确实添加了一个新的依赖项。
from attrs import define
def get_default_value_for_my_field(other_field: str) -> str:
... # lots of code
@define(frozen=True)
class MyClass:
other_field: str
my_field: str
def __init__(self, other_field: str, my_field: str|None):
if not my_field:
my_field = get_default_value_for_my_field(other_field)
self.__attrs_init__(other_field=other_field, my_field=my_field)
1赞
Brian61354270
10/21/2023
#2
将“命名构造函数”类方法添加到您的数据类中:
@dataclasses.dataclass(frozen=True)
class MyClass:
my_field: str
other_field: str
@classmethod
def from_other(cls, other_field: str) -> MyClass:
my_field = default_for_my_field(other_field)
return cls(my_field, other_field)
然后,您可以创建实例作为MyClass
MyClass("my field", "other field")
或
MyClass.from_other("other field")
使用这种方法,将保持为“哑”纯旧数据类。特殊的默认值逻辑仅在用户请求时启动(通过使用“命名构造函数”)。MyClass
评论
0赞
Pastafarianist
10/23/2023
是的,这是我目前的方法。我想我应该在我的条件列表中包括“避免创建额外的构造函数,而只是使用 ”。__init__()
评论