在Python中有没有一种方法可以指定对对象属性的引用?
我希望将一个对象的属性永久链接到另一个对象的属性,这样,只要后者发生更改,前者就会自动更新 我已经尝试使用=使用简单赋值,但这仅在赋值时赋值属性的值,而我希望为属性本身赋值一个引用在Python中有没有一种方法可以指定对对象属性的引用?,python,python-3.x,Python,Python 3.x,我希望将一个对象的属性永久链接到另一个对象的属性,这样,只要后者发生更改,前者就会自动更新 我已经尝试使用=使用简单赋值,但这仅在赋值时赋值属性的值,而我希望为属性本身赋值一个引用 class firstObj: def __init__(self,n): self.name=n self.inA=1 @property def outA(self): return self.inA+2 class secondObj
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的输入
i、 e
so.inA=2-->因此,outA变为4
-->fo.inA变为4
-->fo.outA变为6
(更一般地说,python中有一种方法可以将对变量的引用分配给另一个变量,而不是变量的值,这样a=b就不会将b的值分配给a,而是将b的引用分配给b本身)您不能这样做。Python没有一种方法让一个名称引用另一个名称,这正是您想要的(您希望fo.inA引用so.outA)。名称只能引用值。这个讲座有更多的细节:。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
在本机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
实例的相应属性也将更改。不太可能,除了所示的带有属性的解决方案之外,您只能持有存储变量的命名空间字典和变量名称。这种组合是对该变量的某种引用。