编辑:为了清楚起见,我需要一个class,它将接受许多参数,我知道所有参数都将提供,但有些可能会被传递为None,在这种情况下,我的class将必须提供默认值.

我想用一些默认值设置一个简单的dataclass,如下所示:

@dataclass
class Specs1:
    a: str
    b: str = 'Bravo'
    c: str = 'Charlie'

我希望能够获得第二个字段的默认值,但仍然为第三个字段设置一个值.我无法使用None来执行此操作,因为它被愉快地接受为字符串的值:

r1 = Specs1('Apple', None, 'Cherry') # Specs1(a='Apple', b=None, c='Cherry')

我提出了以下解决方案:

@dataclass
class Specs2:
    def_b: ClassVar = 'Bravo'
    def_c: ClassVar = 'Charlie'
    a: str
    b: str = def_b
    c: str = def_c

    def __post_init__(self):
        self.b = self.def_b if self.b is None else self.b
        self.c = self.def_c if self.c is None else self.c

这似乎是故意的:

r2 = Specs2('Apple', None, 'Cherry') # Specs2(a='Apple', b='Bravo', c='Cherry')

然而,我觉得这很难看,我可能错过了一些东西.我的实际班级将有更多的领域,所以只会变得更丑陋.

编辑:我应该补充一点,传递给类的参数不包含任何参数,我对这方面没有控制权.

推荐答案

我知道这有点晚了,但受Mikeshneberger回答的启发,我对__post_init__函数做了一个小修改,允许您将默认值保留为标准格式:

from dataclasses import dataclass, fields
def __post_init__(self):
    # Loop through the fields
    for field in fields(self):
        # If there is a default and the value of the field is none we can assign a value
        if not isinstance(field.default, dataclasses._MISSING_TYPE) and getattr(self, field.name) is None:
            setattr(self, field.name, field.default)

然后,将其添加到数据类中可以确保在不需要新的默认类的情况下强制执行默认值.

Python-3.x相关问答推荐

将Trio与基于线程的事件侦听器混合使用

PythonPandas 创建一个列并添加到DataFrame

正确的本地react 方式-Django身份验证

我正在try 从 10*3 矩阵中删除随机值并将其变为 10*2 矩阵

为什么不能用格式字符串 '-' 绘制点?

在 groupby 之后,Pandas 在特定类别中获得最常见和最后的值

使用 Python 在特定组的列中设置上限

单击图形时 plotly graph_objects 持久性数据

Pandas 在每组两个条件之间获得时间增量

在字符串中查找正则表达式的所有模式

删除重复项,但将值相加为一

从 yahoo Finance python 一次下载多只股票

Python socket.error: [Errno 13] 权限被拒绝

如何从左到右解包元组?

用 numpy nan 查找列表的最大值

从 IPython 重新加载 Python 扩展模块

计算两个文件的行差异的最有效方法是什么?

使用完整路径激活 conda 环境

将列表列表转换为Python中的字典字典

将 Python 字节转换为无符号 8 位整数