在python中,如何基于作为参数传递的另一个对象的属性更新属性?
好的,让我们从代码开始,因为它非常明确:在python中,如何基于作为参数传递的另一个对象的属性更新属性?,python,python-3.x,oop,object,attributes,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
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?多谢各位
有没有一种方法,不用调用另一个方法,就可以自动
当obj_1.a的值更改时,是否更新obj_2.b?多谢各位
答案是否定的
c_2
的构造函数正在将b
的值设置为other_obj.a
,然后固定b
的值,直到再次明确更改其值。把它看作一个普通的(标量)变量——一旦设置了值,它就不会改变,除非你明确地给它分配一个新的值。
如果要在
c_2
中引用a
的值,应始终将self.other.a
引用为self.other.code>。other
是对传递给构造函数的other_obj
的引用。这是可能的,但您的里程数可能会有所不同,具体取决于您的使用情况:
下面所示的一种方法是实现一个Var类
,为您处理这个问题;将值封装在对象中会绕过“按值传递”,并打开“值”以实现可变性。这是一个不完整(脆弱)的例子;为了使其顺利运行,有许多角落案例需要解决,但要回答您的问题:是的,这绝对是可能的:
其他方法可能使用检查模块
,或元类
,或回调的实现
使用专门的类和回调方法
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)
输出:
基本上,不能这样做的原因是Python变量是通过值传递的,而不是通过引用传递的。Python也没有任何语言机制允许您像其他一些C风格语言一样声明作为引用的变量。您可以通过将值封装在对象中并传递来绕过这一点。首先,谢谢。我不太明白你的最后一句话,因为这已经是我正在做的事情了。我第一次寻找解决问题的方法时,我遇到了使用setter和getter以及其他类似装饰的人。你有什么资源可以让我学习更多关于如何在Python中使用属性的知识吗?编辑:没关系,我想我终于明白了要点。目标是使其在每次“调用”属性时更新其值。是吗?是的,大概是这样;很高兴你从我的回答中获得了更深刻的见解。:)
5
8
10