Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中有没有一种方法可以指定对对象属性的引用?_Python_Python 3.x - Fatal编程技术网

在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
实例的相应属性也将更改。

不太可能,除了所示的带有
属性的解决方案之外,您只能持有存储变量的命名空间字典和变量名称。这种组合是对该变量的某种引用。