所以我遇到了这个问题,我不了解变量以不同的方式显示,这取决于我在将其作为属性的容器中使用的函数。我设法将其简化为以下代码:
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
可以解决此问题,但是我想避免它,因为它看起来很hacky。
在我的真实情况下,包装有点复杂,所以我无法摆脱它。如果您除去包装纸,它将按预期工作。我认为包装后的功能有点像“定居”,但我不知道如何解释。
所以我的问题是2折:
-为什么此代码无法按预期工作(2个输出为0
)?
-我该如何解决?
答案 0 :(得分:1)
由于要使用second_container
创建deepcopy
,因此永远不会调用其__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时发生,而不是在{{1} }时间:
__init__
如果这不可行,那么还有很多其他可能性-例如,您可以将class ContainerParent(object):
@property
def show(self):
return do_wrapping(self._show)
@show.setter
def show(self, shower):
self._show = shower
设置为属性,并将var
行移至其设置器中-但很难说会怎样最好,而又不了解您的实际代码。