如何更改对象属性的值,该属性是对另一个对象属性的引用?

时间:2016-02-09 23:10:52

标签: python oop python-3.x

x.n

如何制作,以便我可以在y内更改x?如果不向{{1}}添加更多功能,是否有一种简单的方法可以做到这一点?

2 个答案:

答案 0 :(得分:1)

好吧,正如其他人已经指出的那样,问题归结为你正在处理imutable objects。意识到这一点,您应该使用可变类型,或使用回调来管理更新。 Adriano Abrantes给出了一个使用可变类型的替代方案的示例,但如果这不是您正在寻找的,那么这里是潜在回调系统的一个例子:

# bad habit to be using the old style class definition (i.e. `class Foo:`)
# the `@property` decorator wont work if you use the old style

class Sync(object):

    def __init__(self, name, value, *dependants):
        """Sync the attribute `name` on all `dependants` when `self.value` is updated"""
        self._name = name
        self._value = value
        self._updating = False
        self._dependants = list(dependants)
        self._update_dependants()

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, x):
        if x != self._value:
            self._value = x
            self._update_dependants()

    def _update_dependants(self):
        self._updating = True
        for d in self._dependants:
            if getattr(d, self._name) != self.value:
                if isinstance(d, Sync):
                    if not d._updating:
                        setattr(d, self._name, self.value)
                else:
                    setattr(d, self._name, self.value)
        self._updating = False

    def add_dependant(self, other):
        self._dependants.append(other)
        self._update_dependants()

    def del_dependnant(self, other):
        self._dependants.remove(other)

    def __repr__(self):
        return "Sync('"+self._name+"': "+repr(self.value)+")"

    def __eq__(self, other):
        if isinstance(other, Sync):
            return self.value == other.value
        else:
            return self.value == other

    def __ne__(self, other):
        return not self.__eq__(other)


s1 = Sync('value', 2)
s2 = Sync('value', 1)
print('setup the Sync objects:')
print('>>> ' + repr(s1) + (' == ' if s1 == s2 else ' != ') + repr(s2))

s1.add_dependant(s2)
s2.add_dependant(s1)
print('add sync objects as dependants of each other:')
print('>>> ' + repr(s1) + (' == ' if s1 == s2 else ' != ') + repr(s2))

s1.value += 1
print('check that value changes transfer from one to the other:')
print('>>> ' + repr(s1) + (' == ' if s1 == s2 else ' != ') + repr(s2))

如果这仍然不能让你满意,我会调查一下名为Traitlets的东西。它是Ipython的一个软件包,它是Project Jupyter的一部分,它强制执行类型检查,简化回调系统,并简化应用程序配置。我已经为该项目做了一段时间的贡献,所以如果您对Traitlets有任何疑问,请随时在这里问我或者在Gitter发布它们,开发团队会回答它们。

答案 1 :(得分:0)

我相信你所做的事情违背了OOP的许多概念,但你可以使用一个列表:

class Bar:
  def __init__(self,n):
    self.n = [n]

class Foo:
  def __init__(self,l):
    self.l = l

x = Bar(2)
print(x.n)
>>>[2]

y = Foo(x.n)
y.l[0] += 1
print(x.n)
>>>[3]