gpt4 book ai didi

Python 数据类 : can you set a default default for fields?

转载 作者:行者123 更新时间:2023-11-28 17:55:49 28 4
gpt4 key购买 nike

我想创建一个数据类基类,其中子类中的所有字段都自动可选且默认为无(如果未提供默认值)。

下面的代码……几乎可以满足我的要求,但又不完全是。它出错的方式就像我从未编写过 __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+ 中可行吗?

最佳答案

我找到了一种修改类 __annotations__ 字段以使字段可选并直接在类上设置属性以提供默认值 None 的方法:

from dataclasses import dataclass

import typing


@dataclass(order=True, frozen=True)
class BaseDictKey:
def __init_subclass__(cls, *args, **kwargs):
for field, value in cls.__annotations__.items():
cls.__annotations__[field] = typing.Union[value, None]
if not hasattr(cls, field):
setattr(cls, field, None)
super().__init_subclass__(*args, **kwargs)


@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'

def __init__(self, *args, **kwargs): # to get rid of PyCharm warning
pass


c = ScoreDictKey()
print(c.catalog, c.dataset) # None foo

关于Python 数据类 : can you set a default default for fields?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58554092/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com