替换Data Class对象中的属性

时间:2018-04-18 20:21:10

标签: python python-3.7 python-dataclasses

我希望替换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)

返回:

U(x=1)
U(x=-1)
V(x=1)

如何在数据类对象中模仿此功能?

4 个答案:

答案 0 :(得分:6)

Python数据类模块有一个公共API,用于在数据类实例上进行字段替换,记录为here。此功能由模块级辅助函数提供:

from dataclasses import replace

使用情况不同于collections.namedtuple,其中此功能是通过生成类型的方法提供的(旁注: namedtuple._replace已记录/公开。此名称选择为被作者称为“后悔” - 请参阅答案末尾的链接。

示例用法:

>>> 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,以及namedtupledataclasses之间的其他设计差异以及一些性能比较。

答案 1 :(得分:0)

dataclass只是基于类型注释属性自动创建特殊__init__方法和许多其他“样板”方法的语法糖。

创建类后,它就像任何其他类一样,它的属性可以被覆盖,实例也可以被复制,例如。

import copy

v_ = copy.deepcopy(v)
v_.x = -1

根据属性的不同,您可能只需要copy.copy

答案 2 :(得分:0)

我知道问题是关于 app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); endpoints.MapFallbackToController("Index", "Fallback"); }); } 的,但是如果您使用的是dataclass,则可以使用attr.evolve而不是attr.s

dataclasses.replace

答案 3 :(得分:0)

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