替换 Data Class 对象中的属性
Replace attributes in Data Class objects
我想替换 dataclass 实例的属性,类似于 namedtuple._replace()
,即制作原始对象的更改副本:
from dataclasses import dataclass
from collections import namedtuple
U = namedtuple("U", "x")
@dataclass
class V:
x: int
u = U(x=1)
u_ = u._replace(x=-1)
v = V(x=1)
print(u)
print(u_)
print(v)
这个returns:
U(x=1)
U(x=-1)
V(x=1)
如何在数据类对象中模拟此功能?
dataclass
只是语法糖,用于自动创建特殊的 __init__
方法和许多其他基于类型注释属性的 "boilerplate" 方法。
一旦class被创建,它就像其他任何东西一样,它的属性可以被覆盖并且实例可以被复制,例如
import copy
v_ = copy.deepcopy(v)
v_.x = -1
根据属性的不同,您可能只需要 copy.copy
。
dataclasses
模块有一个辅助函数,用于实例 (docs) 的字段替换
from dataclasses import replace
用法不同于 collections.namedtuple
,其中功能由生成类型的方法提供(旁注: namedtuple._replace
是 documented/public API,在名称上使用下划线被作者称为“遗憾”,请参阅答案末尾的link。
>>> from dataclasses import dataclass, replace
>>> @dataclass
... class V:
... x: int
... y: int
...
>>> v = V(1, 2)
>>> v_ = replace(v, y=42)
>>> v
V(x=1, y=2)
>>> v_
V(x=1, y=42)
有关设计的更多背景信息,请参阅 PyCon 2018 演讲 - Dataclasses: The code generator to end all code generators。深入讨论了 replace
API,以及 namedtuple
和 dataclasses
之间的其他设计差异,并显示了一些性能比较。
我知道问题是关于 dataclass
,但是如果您使用的是 attr.s
,那么您可以使用 attr.evolve
而不是 dataclasses.replace
:
import attr
@attr.s(frozen=True)
class Foo:
x = attr.ib()
y = attr.ib()
foo = Foo(1, 2)
bar = attr.evolve(foo, y=3)
@dataclass()
class Point:
x: float = dataclasses.Field(repr=True, default=0.00, default_factory=float, init=True, hash=True, compare=True,
metadata={'x_axis': "X Axis", 'ext_name': "Point X Axis"})
y: float = dataclasses.Field(repr=True, default=0.00, default_factory=float, init=True, hash=True, compare=True,
metadata={'y_axis': "Y Axis", 'ext_name': "Point Y Axis"})
Point1 = Point(13.5, 455.25)
Point2 = dataclasses.replace(Point1, y=255.25)
print(Point1, Point2)
我想替换 dataclass 实例的属性,类似于 namedtuple._replace()
,即制作原始对象的更改副本:
from dataclasses import dataclass
from collections import namedtuple
U = namedtuple("U", "x")
@dataclass
class V:
x: int
u = U(x=1)
u_ = u._replace(x=-1)
v = V(x=1)
print(u)
print(u_)
print(v)
这个returns:
U(x=1)
U(x=-1)
V(x=1)
如何在数据类对象中模拟此功能?
dataclass
只是语法糖,用于自动创建特殊的 __init__
方法和许多其他基于类型注释属性的 "boilerplate" 方法。
一旦class被创建,它就像其他任何东西一样,它的属性可以被覆盖并且实例可以被复制,例如
import copy
v_ = copy.deepcopy(v)
v_.x = -1
根据属性的不同,您可能只需要 copy.copy
。
dataclasses
模块有一个辅助函数,用于实例 (docs) 的字段替换
from dataclasses import replace
用法不同于 collections.namedtuple
,其中功能由生成类型的方法提供(旁注: namedtuple._replace
是 documented/public API,在名称上使用下划线被作者称为“遗憾”,请参阅答案末尾的link。
>>> from dataclasses import dataclass, replace
>>> @dataclass
... class V:
... x: int
... y: int
...
>>> v = V(1, 2)
>>> v_ = replace(v, y=42)
>>> v
V(x=1, y=2)
>>> v_
V(x=1, y=42)
有关设计的更多背景信息,请参阅 PyCon 2018 演讲 - Dataclasses: The code generator to end all code generators。深入讨论了 replace
API,以及 namedtuple
和 dataclasses
之间的其他设计差异,并显示了一些性能比较。
我知道问题是关于 dataclass
,但是如果您使用的是 attr.s
,那么您可以使用 attr.evolve
而不是 dataclasses.replace
:
import attr
@attr.s(frozen=True)
class Foo:
x = attr.ib()
y = attr.ib()
foo = Foo(1, 2)
bar = attr.evolve(foo, y=3)
@dataclass()
class Point:
x: float = dataclasses.Field(repr=True, default=0.00, default_factory=float, init=True, hash=True, compare=True,
metadata={'x_axis': "X Axis", 'ext_name': "Point X Axis"})
y: float = dataclasses.Field(repr=True, default=0.00, default_factory=float, init=True, hash=True, compare=True,
metadata={'y_axis': "Y Axis", 'ext_name': "Point Y Axis"})
Point1 = Point(13.5, 455.25)
Point2 = dataclasses.replace(Point1, y=255.25)
print(Point1, Point2)