社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在python中,如何使用不可变类型对copy执行浅更新?(结构共享)

Rob Fitzgerald • 5 年前 • 1599 次点击  

我将从scala来到python,在这里,对于给定的(case)类,我可以执行一个复制,在同一步骤中,指定修改字段的任意子集。斯卡拉的情况是这样的:

case class Foo(year: Int, album: String)

// here's a Foo
val foo: Foo = Foo(1973, "Larks Tongues In Aspic")

// updated album with (shallow) copy of year in one step
val nooFoo: Foo = foo.copy(album = "Black Beauty: Live at the Fillmore West")

(为了便于复制,示例保持简单)

我见过很多关于复制不可变数据的stacko问题,但是没有更新它。我希望在不可变更新的上下文中有特殊的结构共享。

我已经看过用 namedtuple ,或引发错误 __setattr__ 使一个不可变的对象。我想我可以用一些方法 object.__setattr__ 这似乎让当地人负担过重 __塞塔特__ 方法。 但是,这是否意味着我需要为可能执行的每个更新组合实现一个方法? 这意味着我需要定义最多N个!更新n个字段的函数(理论上)。对于有两个字段的类,可能如下所示:

import copy

class Foo:
  self.year = None
  self.album = None

  def __init__(self, year, album):
    object.__setattr__(self, "year", year)
    object.__setattr__(self, "album", album)

  def __setattr__(self):
    raise TypeError("i pity the Foo")

  def update_a(self, new_year):
    noo_foo = copy.copy(self)
    object.__setattr__(noo_foo, "year", new_year)
    return noo_foo

  def update_b(self, new_album):
    noo_foo = copy.copy(self)
    object.__setattr__(noo_foo, "album", new_album)
    return noo_foo


什么是pythonic方法来执行不可变的对象更新(带有字段修改的副本),而不陷入编写大量类样板文件的陷阱?或者,我是不是错过了一些简单的东西?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/48346
 
1599 次点击  
文章 [ 1 ]  |  最新文章 5 年前
ShadowRanger
Reply   •   1 楼
ShadowRanger    5 年前

namedtuple 支持此行为 the ._replace method (尽管前面有下划线,但这是一个公共方法,它的前缀只是下划线,以避免与用户定义的字段冲突),而且它实际上是不可变的(覆盖 __setattr__ 并不是完全不变的)。

from collections import namedtuple

Foo = namedtuple('Foo', 'year album')

foo1 = Foo(1996, 'Album1')
foo2 = foo1._replace(year=1997)

如果不需要与较旧版本的Python兼容,并且希望有一种简单的方法向类中添加其他行为, the newer typing.NamedTuple 是一种更灵活的方法来命名命名元组。