提问人:Anthon 提问时间:10/4/2023 最后编辑:Anthon 更新时间:10/4/2023 访问量:71
数据类使用 InitVar 默认值来设置实例属性
dataclasses use InitVar default to set instance attribute
问:
在数据类中为类型化变量提供默认值时,该属性
对于该变量已设置(实际上,对于缺少默认值的变量,该属性似乎是
在 中主动删除。InitVar
dataclasses:_process_class()
from dataclasses import dataclass, InitVar, fields
@dataclass
class HasDefault:
abc: int = 18
xyz: InitVar[str] = 'oops'
def __post_init__(self, xyz):
self.abc += len(xyz)
@dataclass
class NoHasDefault:
abc: int
xyz: InitVar[str]
def __post_init__(self, xyz):
self.abc += len(xyz)
hd = HasDefault(abc=42, xyz='so long...')
print('field names', [field.name for field in fields(hd)])
print(hd, hd.abc, hd.xyz)
print()
hd2 = HasDefault(abc=42)
print('field names', [field.name for field in fields(hd2)])
print(hd2, hd2.abc, hd2.xyz)
print()
hd3 = HasDefault()
print('field names', [field.name for field in fields(hd3)])
print(hd3, hd3.abc, hd3.xyz)
print()
nhd = NoHasDefault(abc=42, xyz='so long...')
print('field names', [field.name for field in fields(nhd)])
print(nhd, getattr(nhd, 'xyz', 'no attribute xyz'))
这给了:
field names ['abc']
HasDefault(abc=52) 52 oops
field names ['abc']
HasDefault(abc=46) 46 oops
field names ['abc']
HasDefault(abc=22) 22 oops
field names ['abc']
NoHasDefault(abc=52) no attribute xyz
为什么为类型化变量设置属性(当存在默认值时)?我希望永远不会设置此属性,因为它仅用于初始化。这是一个错误吗?xyz
InitVar
mypy
实际上抱怨这些实例没有属性,所以它的处理方式似乎不同。xyz
InitVar
因此,我需要添加一些额外的行才能从 YAML 加载这样的代码,以便以与 YAML 映射中的值相同的方式工作
将用于设置属性,而不是默认值。所以你可以做的(在'ruamel.yaml>0.17.34中)是:dataclass
from dataclasses import dataclass, InitVar
from typing import ClassVar
from ruamel.yaml import YAML
yaml = YAML()
@yaml.register_class
@dataclass
class HasDefault:
yaml_tag: ClassVar = '!has_default' # if not set the class name is taken ('!HasDefault')
abc: int
xyz: InitVar[str] = 'oops'
def __post_init__(self, xyz):
self.abc += len(xyz)
yaml_str = """\
!has_default
abc: 42
xyz: hello world
"""
data = yaml.load(yaml_str)
print(data, data.xyz == 'oops')
给:
HasDefault(abc=53) True
否则就等于data.xyz
hello world
答: 暂无答案
评论