gpt4 book ai didi

python - 如何深度复制具有包装函数的对象?

转载 作者:行者123 更新时间:2023-11-28 18:00:57 24 4
gpt4 key购买 nike

所以我遇到了这个问题,我不明白一个变量以不同的方式显示,具体取决于我在容器中使用的函数,将它作为一个属性。我设法将其归结为以下代码:

import copy
from functools import wraps


def do_wrapping(func):
@wraps(func)
def wrapper(*args):
return func(*args)
return wrapper


class Container:
def __init__(self, var):
self.var = var
self.show = self._show_method

@property
def show(self):
return self._show

@show.setter
def show(self, shower):
self._show = do_wrapping(shower)

def _show_method(self):
print(self.var)

first_container = Container(1)
second_container = copy.deepcopy(first_container)
second_container.var = 0
second_container.show()
second_container._show_method()

我希望这两种方法都打印出 0,但第一种打印出 1。使用这一行 second_container.show = second_container._show_method 解决了这个问题,但我想避免它,因为它看起来很老套。

在我的真实案例中,包装有点复杂,所以我无法摆脱它。如果您移除包装,它会按预期工作。我假设包装后,该功能有点“一成不变”,但我不知道如何解释它。

所以我的问题有两个:- 为什么这段代码没有按预期工作(2 个输出为 0)?- 我该如何解决?

最佳答案

因为您正在使用 deepcopy 创建 second_container,它的 __init__ 方法永远不会被调用,所以它的 _show属性是从 first_container 中复制的。由于 first_container._show 是一个包装 first_container._show_method 的函数,这就是您调用 second_container.show()

时得到的结果

对于您的简单示例,您可以只调用 second_container.__init__(0) 而不是 second_container.var = 0。这有点不寻常,但它可能适用于您的实际代码。

如果您不能调用复制对象的 __init__ 方法,我认为我的首选方法是在调用 show getter 时进行函数包装,而不是比 __init__ 时间:

class ContainerParent(object):
@property
def show(self):
return do_wrapping(self._show)

@show.setter
def show(self, shower):
self._show = shower

如果这不可行,那么还有很多其他可能性 - 例如,您可以将 var 设为属性并移动 self.show = self._show_method line into its setter - 但如果不了解您的实际代码,很难说什么是最好的。

关于python - 如何深度复制具有包装函数的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55763862/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com