【发布时间】:2020-02-21 13:04:37
【问题描述】:
我想创建一个数据类基类,其中子类中的所有字段都是自动可选的,默认为无(如果没有提供默认值)。
以下代码...似乎几乎可以满足我的要求,但并不完全。它的错误方式与我从未编写过 __init_subclass__ 的方式相同(即抱怨未填充的参数)......也许是因为我的代码在数据类魔法发生之后运行?
@dataclass(order=True, frozen=True)
class BaseDictKey:
def __init_subclass__(cls, *args, **kwargs):
super().__init_subclass__(*args, **kwargs)
# noinspection PyUnresolvedReferences
for field in cls.__dataclass_fields__.values():
field.default = None if field.default is None else field.default
field.type = typing.Union[field.type, NoneType]
@dataclass(order=True, frozen=True)
class ScoreDictKey(BaseDictKey):
catalog: str # magically becomes catalog: Optional[str] = None
dataset: str = 'foo' # magically becomes dataset: Optional[str] = 'foo'
(如果你想知道我为什么想要这个,我有另一个基类,它使用这些 BaseDictKeys 期望子类中的任何和所有字段都是可选的。我想我可以引发异常如果我检测到某些东西不是可选的,但这看起来更丑。)
这在 Python 3.7+ 中可行吗?
【问题讨论】:
-
请描述“不完全”的方式,这样我们就不必猜测了。
-
编辑了原文。这是我的更改:它的错误方式与我从未编写过
__init_subclass__的方式相同(即抱怨未填充的参数)......也许是因为我的代码在数据类魔法发生后运行? -
这条线应该做什么?
field.default = None if field.default is None else field.default -
如果你看一下 ScoreDictKey.dataset,它应该更有意义,但基本上:如果提供了默认值,不要用 None 覆盖它,但如果没有提供任何内容,请将默认设置为没有。我没有这样做
None if not field.default else field.default因为这不适用于 falsy-non-None 默认值(0、''、[] 等)
标签: python python-3.x python-dataclasses