在python中,如何基于作为参数传递的另一个对象的属性来更新属性?

时间:2019-05-05 04:11:28

标签: python python-3.x oop object attributes

好的,让我们从代码开始,因为它非常明确:

class c_1:
    def __init__(self):
        self.a = 5

class c_2:
    def __init__(self,other_obj):
        self.other = other_obj
        self.b = self.other.a

obj_1 = c_1()
obj_2 = c_2(obj_1)
print(obj_2.b)
>>>5
obj_1.a = 8
print(obj_2.b)
>>>5

这是问题所在。我知道obj_2.b的第二次调用应该返回5,但我希望它返回8。

我认为我真正想要的是将obj_1.a的值通过obj_2.b的引用传递(此示例非常简单,但是在我的实际代码中,obj_2使用了更多来自obj_1的属性)

有没有一种方法,无需调用其他方法,就可以在obj_1.a的值更改时自动更新obj_2.b?谢谢。

2 个答案:

答案 0 :(得分:2)

  

有没有一种方法,无需调用其他方法,即可自动   当obj_1.a的值更改时更新obj_2.b吗?谢谢

答案是否定的。

c_2的构造函数正在将b的值设置为other_obj.a,然后将b的值固定,直到再次明确地更改其值。将其视为普通(标量)变量-设置该值后,除非您明确为其分配新值,否则它不会更改。

如果要引用ac_2的值,则应始终引用self.other.a,因为self.other是对传递给other_obj的引用构造函数。

答案 1 :(得分:1)

可能,但是您的里程可能会因使用情况而异:

下面显示的一种方法是实现Var class来为您处理此问题;将值封装在对象内部可避免“ 按值传递”,并打开“ ”以实现可变性。这是一个不完整(且脆弱)的示例;有很多紧急情况需要解决,以使其顺利运行,但要回答您的问题:是的,绝对有可能:

其他方法可能使用inspect modulemetaclassescallbacks的实现。

tkinter in the python standard library使用专门的类和回调方法。

class Var:
    def __init__(self, value):
        self._value = value

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

    @value.setter
    def value(self, value):
        self._value = value

    def __repr__(self):
        return str(self._value)


class IntVar(Var):

    def __iadd__(self, other: int):
        self._value = self._value + other
        return self.value


class c_1:
    def __init__(self):
        self._a = IntVar(5)

    @property
    def a(self):
        return self._a

    @a.setter
    def a(self, value):
        self._a.value = value


class c_2:
    def __init__(self, other_obj):
        self.other = other_obj
        self.b = self.other.a


obj_1 = c_1()
obj_2 = c_2(obj_1)
print(obj_2.b)
obj_1.a = 8
print(obj_2.b)
obj_1.a += 2
print(obj_2.b)

输出:

5
8
10