有没有办法检查默认值是否显式传递给数据类的实例?
Is there a way to check if the default values were explicitly passed in to an instance of a dataclass`
考虑以下 python 代码:
from dataclasses import dataclass
@dataclass
class Registration:
category: str = 'new'
@dataclass
class Car:
make: str = None
category: str = None
reg: Registration = None
def __post_init__(self):
''' fill in any missing fields from the registration of car '''
if self.reg:
for var in vars(self.reg):
if not self.var:
self.var = self.reg.var
r = Registration()
a = Car(make='ford', category='used', reg=r)
# its unknown if b is used/new, so we explicitly pass it None
b = Car(make='ford', category=None, reg=r)
在上面的例子中,__post_init__
应该填充 Car
class 中的字段,如果它在创建 Car
对象期间没有被传入。但是,如果 None 作为字段值显式传入(在本例中为 category
),则不应从 Registration 对象中覆盖它。但是上面的代码确实如此。我如何检测在对象创建期间显式传递的值与默认值?
如果有办法区分
None
显式传递 vs 对象通过
它的默认值。在像你这样的情况下,一种技术是使用
一种作为默认值的哨兵值。
@dataclass
class Car:
NO_ARG = object()
make: str = None
category: str = NO_ARG
reg: Registration = None
def __post_init__(self):
if self.reg:
for var in vars(self.reg):
if getattr(self, var) is self.NO_ARG:
setattr(self, var, getattr(self.reg, var))
但是,你也可能会把你自己发现的尴尬处境
作为一个信号,也许有更好的方法来模拟你的
对象。在不了解更多情况下
更广泛的背景很难提供明确的建议,但是
我会说你目前的策略让我觉得可疑,所以我
会鼓励您多考虑一下您的 OO 计划。
举一个替代模型的例子,而不是使用注册来
覆盖汽车的属性,您可以改为构建 属性
在 Car 属性时公开 Registration 属性
不见了。 class 的用户可以决定他们是否想要
该类别严格来自汽车,或者他们很乐意接受
来自注册的回退值(如果可用)。这种方法
也有权衡。
@dataclass
class Car:
make: str = None
category: str = None
reg: Registration = None
@property
def category_reg(self):
if self.category is None and self.reg:
return self.reg.category
else:
return self.category
考虑以下 python 代码:
from dataclasses import dataclass
@dataclass
class Registration:
category: str = 'new'
@dataclass
class Car:
make: str = None
category: str = None
reg: Registration = None
def __post_init__(self):
''' fill in any missing fields from the registration of car '''
if self.reg:
for var in vars(self.reg):
if not self.var:
self.var = self.reg.var
r = Registration()
a = Car(make='ford', category='used', reg=r)
# its unknown if b is used/new, so we explicitly pass it None
b = Car(make='ford', category=None, reg=r)
在上面的例子中,__post_init__
应该填充 Car
class 中的字段,如果它在创建 Car
对象期间没有被传入。但是,如果 None 作为字段值显式传入(在本例中为 category
),则不应从 Registration 对象中覆盖它。但是上面的代码确实如此。我如何检测在对象创建期间显式传递的值与默认值?
如果有办法区分
None
显式传递 vs 对象通过
它的默认值。在像你这样的情况下,一种技术是使用
一种作为默认值的哨兵值。
@dataclass
class Car:
NO_ARG = object()
make: str = None
category: str = NO_ARG
reg: Registration = None
def __post_init__(self):
if self.reg:
for var in vars(self.reg):
if getattr(self, var) is self.NO_ARG:
setattr(self, var, getattr(self.reg, var))
但是,你也可能会把你自己发现的尴尬处境 作为一个信号,也许有更好的方法来模拟你的 对象。在不了解更多情况下 更广泛的背景很难提供明确的建议,但是 我会说你目前的策略让我觉得可疑,所以我 会鼓励您多考虑一下您的 OO 计划。
举一个替代模型的例子,而不是使用注册来 覆盖汽车的属性,您可以改为构建 属性 在 Car 属性时公开 Registration 属性 不见了。 class 的用户可以决定他们是否想要 该类别严格来自汽车,或者他们很乐意接受 来自注册的回退值(如果可用)。这种方法 也有权衡。
@dataclass
class Car:
make: str = None
category: str = None
reg: Registration = None
@property
def category_reg(self):
if self.category is None and self.reg:
return self.reg.category
else:
return self.category