我想将一个对象的属性永久链接到另一个对象的属性,这样只要更改了后者,该对象就会自动更新。
我尝试使用使用=的简单分配,但这仅在分配时分配属性的值,而我想分配对属性本身的引用。
class firstObj:
def __init__(self,n):
self.name=n
self.inA=1
@property
def outA(self):
return self.inA+2
class secondObj:
def __init__(self,n):
self.name=n
self.inA=1
@property
def outA(self):
return self.inA*2
fo=firstObj("FO")
so=secondObj("SO")
fo.inA=so.outA
我正在尝试将so的输出链接到fo的输入
即
so.inA = 2
-> so.outA变为4
-> fo.inA变为4
-> fo.outA变为6
(通常,python中有一种方法可以将对变量的引用分配给另一个变量,而不是变量的值,以便a = b不会将b的值分配给a而是对b本身的引用)
答案 0 :(得分:1)
python中的变量只是字典映射var name = value,如果您尝试print(globals())
,它将注意到所有模块变量的字典映射
如果您需要实现所需的目标,可以在类定义中执行以下操作:
class firstObj:
def __init__(self,n, obj=None):
self.name=n
self._inA=1
self.obj = obj
@property
def inA(self):
if self.obj is not None:
self._inA = self.obj.outA
return self._inA
@property
def outA(self):
return self.inA+2
class secondObj:
def __init__(self,n):
self.name=n
self.inA=1
@property
def outA(self):
return self.inA*2
so=secondObj("SO")
fo=firstObj("FO", so)
# fo.inA=so.outA
so.inA=2
print(so.outA) # becomes 4
print(fo.inA) # becomes 4
print(fo.outA) # becomes 6
输出:
4
4
6
答案 1 :(得分:1)
在本机Python中,对此没有直接支持。但是,您可以使用回调模拟此功能:
from functools import partial
class Teller:
def __init__(self, name):
super().__setattr__('_callbacks', {})
self.name = name
def register(self, attr, callback):
if attr in self._callbacks:
self._callbacks[attr].append(callback)
else:
self._callbacks[attr] = [callback]
def __setattr__(self, attr, value):
if attr in self._callbacks:
for callback in self._callbacks[attr]:
callback(value)
else:
self._callbacks[attr] = []
super().__setattr__(attr, value)
class Asker:
def __init__(self, name):
self.name = name
def bind(self, self_attr, other, other_attr):
other.register(other_attr, partial(setattr, self, self_attr))
setattr(self, self_attr, getattr(other, other_attr))
teller = Teller('Teller')
teller.teller_value = 5
asker = Asker('Asker')
asker.bind('asker_value', teller, 'teller_value')
print(f'teller_value is now {teller.teller_value}')
print(f'asker_value is now {asker.asker_value}')
teller.teller_value = 10
print(f'teller_value is now {teller.teller_value}')
print(f'asker_value is now {asker.asker_value}')
输出:
teller_value is now 5
asker_value is now 5
teller_value is now 10
asker_value is now 10
基本上,这需要Asker
的实例将其属性之一绑定到Teller
的实例之一;然后,只要Teller
实例修改该属性,Asker
实例的相应属性也会更改。
答案 2 :(得分:0)
您不能这样做。 Python没有办法让名称引用另一个名称,这就是您想要的名称(您希望fo.inA引用so.outA)。名称只能引用值。这次讲座有更多详细信息:Python Names and Values。