如何在功能上更新数据类?

Max*_*ber 0 python python-dataclasses

我想复制冻结数据类的实例,仅更改一个字段(“功能更新”)。

这是我尝试过的

from dataclasses import dataclass, asdict    
@dataclass(frozen = True)    
class Pos:    
    start: int    
    end: int    
     
def adjust_start(pos: Pos, delta: int) -> Pos:    
   # TypeError: type object got multiple values for keyword argument 'start'    
   return Pos(**asdict(pos), start = pos.start + delta)    
     
adjust_start(Pos(1, 2), 4)   
Run Code Online (Sandbox Code Playgroud)

我正在寻找什么:

  • 有没有比dicts 转换更直接的方法?
  • 如何解决这个问题TypeError:如果有一种方法可以在功能上更新 kwargs,那么这是可行的。

在 Scala 中,案例类(Scala 数据类)的功能更新可以这样完成pos.copy(start = pos.start + delta)

AKX*_*AKX 6

dataclasses.replace()来救援。

dataclasses.replace(obj, /, **changes)创建一个与 相同类型的新对象obj,并将字段替换为 中的值changes

import dataclasses


@dataclasses.dataclass(frozen=True)
class Pos:
    start: int
    end: int


def adjust_start(pos: Pos, delta: int) -> Pos:
    return dataclasses.replace(pos, start=pos.start + delta)


p = adjust_start(Pos(1, 2), 4)
Run Code Online (Sandbox Code Playgroud)

就我个人而言,我可能会使用adjust数据类本身:

import dataclasses


@dataclasses.dataclass(frozen=True)
class Pos:
    start: int
    end: int

    def adjust(self, *, start: int, end: int) -> "Pos":
        return dataclasses.replace(
            self,
            start=self.start + start,
            end=self.end + end,
        )


p = Pos(1, 2).adjust(start=4)
Run Code Online (Sandbox Code Playgroud)