【问题标题】:In python, how to update attribute based on attribute of another object passed as an argument?在python中,如何根据作为参数传递的另一个对象的属性更新属性?
【发布时间】:2019-09-23 02:51:24
【问题描述】:

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

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 而不调用其他方法?谢谢。

【问题讨论】:

  • 基本上,不能这样做的原因是 Python 变量是按值传递的,而不是按引用传递的。 Python 也没有任何语言机制允许您声明作为引用的变量,就像其他一些 C 风格的语言一样。
  • 您可以通过将值封装在对象中并传递它来规避这种情况。

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


【解决方案1】:

这是可能的,但您的里程可能会有所不同,具体取决于您的用例:

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

其他方法可能使用inspect module,或metaclasses,或callbacks的实现。

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

【讨论】:

  • 第一次寻找解决问题的方法时,我遇到了使用 setter 和 getter 以及其他类似装饰的人。你有什么资源可以让我了解更多关于如何在 Python 中使用属性的信息吗?编辑:没关系,我想我终于明白了它的要点。目标是使每次“调用”属性时,都会更新其值。对吗?
  • 是的,类似的;很高兴您从我的回答中获得了更深入的了解。 :)
【解决方案2】:

有没有办法在不调用其他方法的情况下自动 当 obj_1.a 的值改变时更新 obj_2.b ?谢谢

答案是否定的。

c_2 的构造函数将b 的值设置为other_obj.a,然后b 的值是固定的,直到您再次显式更改其值。将其视为普通(标量)变量 - 一旦设置了值,在您明确为其分配新值之前它不会改变。

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

【讨论】:

  • 首先谢谢你。我不太明白你的最后一句话,因为这就是我正在做的事情。
猜你喜欢
  • 2019-12-09
  • 1970-01-01
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-11
  • 1970-01-01
相关资源
最近更新 更多