Python 将一个名称链接到另一个名称
我有以下代码:Python 将一个名称链接到另一个名称,python,reference,Python,Reference,我有以下代码: class B: def __init__(self, msg): self.msg = msg class A: def __init__(self, msg): self.msg = msg self.b = B(self.msg) def update(self, msg): self.msg = msg a = A('hello') print a.msg print a.
class B:
def __init__(self, msg):
self.msg = msg
class A:
def __init__(self, msg):
self.msg = msg
self.b = B(self.msg)
def update(self, msg):
self.msg = msg
a = A('hello')
print a.msg
print a.b.msg
a.update('bye')
print a.msg
print a.b.msg
其中打印:
hello
hello
bye
hello
这不是我想要的。我需要的是
a.b.msg
被“链接”到a.msg
:a.b.msg
必须始终引用与a.msg
相同的对象,即使在重新绑定a.msg
。这可能吗?我如何才能做到这一点?您可以使用一个属性:
class A(object):
def __init__(self, msg):
self.b = B(msg)
@property
def msg(self):
return self.b.msg
@property.setter
def msg(self, value):
self.b.msg = value
与你想要的相比,我有点落后。在这里,我总是将
a.msg
链接到a.b.msg
,而不是反过来,但实际上在这一点上主要是语义。这些变化应该是双向传播的,所以实际上没有什么实际差异。 < P>你的实际问题是,你想要一个类似于C++中引用调用的行为。要实现这一点,您可以做的是使用一些小技巧来模拟内存位置。其工作的原因可以在中找到,它与python的可变和不可变对象有关
class ref:
def __init__(self, obj): self.obj = obj
def get(self): return self.obj
def set(self, obj): self.obj = obj
class B:
def __init__(self, msg):
self.msg = msg
class A:
def __init__(self, msg):
self.msg = ref(msg)
self.b = B(self.msg)
def update(self, msg):
self.msg.set(msg)
a = A('hello')
print a.msg.get() #hello
print a.b.msg.get() #hello
a.update('bye')
print a.msg.get() #bye
print a.b.msg.get() #bye
但是,如果这意味着对代码的更改太多,您还可以在每个函数中定义一个方法msg(self)
,使用msg
,将msg
重命名为message
或其他任何内容。
这样,您可以通过调用a.msg()
来获取字符串,例如,这将减少对现有代码的更改。但我担心,如果不对代码进行任何更改,就无法解决您的问题
示例二,使用msg()
方法:
class B:
def __init__(self, msg):
self.message = msg
def msg(self):
return self.message.get()
class A:
def __init__(self, msg):
self.message = ref(msg)
self.b = B(self.message)
def update(self, msg):
self.message.set(msg)
def msg(self):
return self.message.get()
a = A('hello')
print a.msg() #hello
print a.b.msg() #hello
我看到的第三种解决方案是使用列表
,而不是引用类:
class B:
def __init__(self, msg):
self.msg = msg
class A:
def __init__(self, msg):
self.msg = [msg]
self.b = B(self.msg)
def update(self, msg):
self.msg[0] = msg
a = A('hello')
print a.msg[0] #hello
print a.b.msg[0] #hello
a.update('bye')
print a.msg[0] #bye
print a.b.msg[0] #bye
一般来说,您可以使用任何其他可变对象来实现此目的,但请注意,您不能重新分配某些“子类”中的可变对象,如
B
,在您的示例中。为什么B
不能跟踪a
并使用a.msg
获取其msg
class MockA:
def __init__(self, msg):
self.msg = msg
class B:
def __init__(self, a):
if isinstance(a, A):
self._a = a
else:
self._a = MockA(a)
@property
def msg(self):
return self._a.msg
class A:
def __init__(self, msg):
self.msg = msg
self.b = B(self)
def update(self, msg):
self.msg = msg
a = A('hello')
print a.msg
print a.b.msg
a.update('bye')
print a.msg
print a.b.msg
b = B('here')
print b.msg
印刷品:
hello
hello
bye
bye
here
它们必须是字符串吗?在
update
方法中添加self.b.msg=msg
。我希望这是自动发生的,而不是用手强迫。背景是,我可以使用父对象的数据作为缓存属性拥有许多子对象,我甚至无法枚举这些子对象。@wnnmaw:它们可以是字符串,也可以是其他内容。解决方案应支持任何类型的对象字符串,因为它们是不可变的。我不想更新self.b.msg:还有self.c.msg,…,一个不确定的数字:对象本身是缓存属性,我无法枚举。这很有趣,但必须添加.get()
意味着对我的code@jeckyll2hide很抱歉这是我想到的最好的主意。。。我会更新,如果我找到一个更好,更容易使用的方式@我更新了我的答案。