3

我有一个带有可变字段(列表)的数据类。我希望实现的是该字段永远不会是 None,即使在 __init__ 调用中明确设置为 None 也是如此。在一个普通的类中,这将是微不足道的:

class A:
    def __init__(self, l: Optional[List[int]] = None):
        if l is None:
            l = []
        self.l = l

有没有办法只使用dataclasses.field函数来实现相同的结果,即不显式实现 __init__ 方法(​​当类有很多属性时会很麻烦)?default_factory当提供的 init 参数为 None 时,我可以强制 dataclasses.field 调用它吗?

4

2 回答 2

4

我不认为,可以直接强制在显式提供的 None 值上调用 default_factory 。但是您可以使用该__post_init__方法显式检查 None 并提供 default_value,特别是如果您必须检查许多属性。

您可以使用该fields函数自动扫描数据类的None值并为这些属性调用 default_factory(如果提供了):

from dataclasses import dataclass, field, fields, MISSING
from typing import List

@dataclass
class A:
    l: List[int] = field(default_factory=list)

    def __post_init__(self):
        for f in fields(self):
            value = getattr(self, f.name)   
            if value is None and not f.default_factory is MISSING:
                setattr(self, f.name, f.default_factory())

s = A([1,2])
print(s.l)  # [1,2]

t = A(None)
print(t.l)  # []
于 2019-04-24T22:06:17.943 回答
1

__post_init__您可以使用将设置为空列表的方法获得所需的结果,self.l即使它是None

@dataclass
class A:
    l: Optional[List[int]]

    def __post_init__(self):
        self.l = self.l or []


a = A(None)
print(a.l)  # []
于 2019-04-24T21:57:49.880 回答