Вложенная функция генератора Python: внешняя функция не отражает изменения в объекте - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть функция генератора (newfunc), которая возвращает объект (класса X) из другой функции генератора (func) следующим образом:

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». Разве оба объекта не должны были быть изменены? В частности, что нужно сделать, чтобы оба варианта изменились?

1 Ответ

0 голосов
/ 26 апреля 2018

Операции присваивания пользовательских объектов не копируют и не перезаписывают их. x1 и x2 являются переменными, содержащими ссылки на их соответствующие объекты. Когда вы пишете:

x1 = x2

Вы говорите: «x1 должен ссылаться на тот же объект, что и x2». Вы никоим образом не изменяете объект, на который изначально ссылается x1. Если вы хотите, чтобы только атрибут state копировался с одного объекта на другой, вам нужно сделать:

x1.set_state(x2.get_state())

Что вызывает set_state для объекта, на который ссылается x1 (xobj1).

И так далее, для каждого атрибута, который необходимо передать. Чтобы сделать его чище, вы можете создать новый метод в классе X:

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

Кроме того, чтобы сделать методы получения и очистки более чистыми, вы должны изучить properties , который является "чистым" способом в python для создания инкапсулированных атрибутов.

...