M.w*_*wol 10 python iteration attributes class python-dataclasses
是否可以在Python中迭代数据类实例的属性?例如,我想在__post_init__double 整数属性中:
from dataclasses import dataclass, fields
@dataclass
class Foo:
a: int
b: int
def __post_init__(self):
self.double_attributes()
def double_attributes(self):
for field in fields(Foo):
field = field*2
x = {
'a': 1,
'b': 2
}
y = Foo(**x)
>>> TypeError: unsupported operand type(s) for *: 'Field' and 'int'
Run Code Online (Sandbox Code Playgroud)
如何访问类实例的值并将其设置为如下所示但在循环中的其他值?
@dataclass
class Foo:
a: int
b: int
def __post_init__(self):
self.double_a()
self.double_b()
def double_a(self):
self.a = self.a*2
def double_b(self):
self.b = self.b*2
Run Code Online (Sandbox Code Playgroud)
rv.*_*tch 13
您非常接近,但dataclasses.fields实际上返回了一个Field对象元组。至少在我的例子中,返回类型似乎没有正确注释,但这很容易修复。
from dataclasses import dataclass, fields, Field
from typing import Tuple
@dataclass
class Foo:
a: int
b: int
def __post_init__(self):
self.double_attributes()
def double_attributes(self):
# Note the annotation added here (tuple of one or more
# `dataclasses.Field`s)
cls_fields: Tuple[Field, ...] = fields(self.__class__)
for field in cls_fields:
# This check is to avoid fields annotated with other types
# such as `str`
if issubclass(field.type, int):
new_val = getattr(self, field.name) * 2
setattr(self, field.name, new_val)
Run Code Online (Sandbox Code Playgroud)
但是,如果您多次运行此操作(例如创建许多Foo对象),那么缓存整数字段列表可能会稍微高效一些。例如,以下是我可能建议的伪代码:
integer_fields: ClassVar[Frozenset[Field]] = frozenset(f for f in fields(cls) if issubclass(f.type, int))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14623 次 |
| 最近记录: |