当提供的参数为None时,是否可以强制数据类字段调用其default_factory?

时间:2019-04-24 21:18:36

标签: python python-dataclasses

我有一个带有可变字段(列表)的数据类。我希望实现的是,即使在__init__调用中显式设置为None时,该字段也永远不会为None。在普通的类中,实现起来很简单:

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

有没有一种方法可以仅使用dataclasses.field函数来实现相同的结果,即不显式实现__init__方法(当类具有很多属性时会很麻烦)?当提供的init参数为None时,是否可以强制dataclasses.field调用其default_factory

2 个答案:

答案 0 :(得分:3)

我不认为,可以直接强制在提供的显式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)  # []

答案 1 :(得分: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)  # []