首页 > 解决方案 > Python嵌套生成器函数:外部函数不反映对象的变化

问题描述

我有一个生成器函数(newfunc),它通过以下方式从另一个生成器函数(func)产生一个(X类)对象:

from contextlib import contextmanager

class X(object):

    def __init__(self):
        self.state = 'oldstate'

    def set_state(self, state):
        self.state = state

    def get_state(self):
        return self.state

xobj1 = X()
xobj2 = X()

@contextmanager
def func(xobj, someVar):
    print someVar
    yield xobj

@contextmanager
def newfunc():
    with func(xobj1, 1) as x1:
        with func(xobj2, 2) as x2:
            yield x2
            x1 = x2 %setting to potentially changed object.

with newfunc() as x:
    x.set_state('newstate')

现在,由于 x1 被设置为 x2,我希望 xobj1 的状态也反映“newstate”。但是,只有 xobj2 的状态设置为“newstate”。两个对象不应该都被改变了吗?具体来说,应该做些什么来确保两者都发生变化?

标签: pythonpython-2.7generator

解决方案


自定义对象的赋值操作不会复制或覆盖它们。x1并且x2是包含对其各自对象的引用的变量。当你写:

x1 = x2

您是在说:“x1 应该与 x2 引用相同的对象”。您绝不会更改最初引用的对象x1。如果您只想将state属性从一个对象复制到另一个对象,则需要执行以下操作:

x1.set_state(x2.get_state())

它调用set_statex1 (xobj1) 引用的对象。

依此类推,对于需要传输的每个属性。为了让它更简洁,你可以在类 X 中创建一个新方法:

def copy_state(self, other):
    self.set_state(other.get_state())
    self.set_x(other.get_x())
    ...

此外,为了使 getter 和 setter 更干净,您应该查看属性,这是 python 中用于制作封装属性的“干净”方式。


推荐阅读