在类

时间:2018-07-06 22:56:00

标签: python

我希望能够在Test类中更改变量的引用

class Test():
    def change(self, Other_Class):
        self.__class__ = Other_Class.__class__
        self = Other
class Other():
    def set_data(self, data):
        self.data = data
    def one(self):
        print('foo')

a = Test()
b = Other()
b.set_data([1,2,3])
a.change(b)
a.data

AttributeError: 'Other' object has no attribute 'data'

如何更改对a的引用,使其成为我传递给Test()的变量。

我也希望此方法也适用于内置数据类型,但是为此我会得到另一个错误。

什么是最好的方法?

1 个答案:

答案 0 :(得分:1)

Test.change内,self是一个参数,而参数只是局部变量。

重新绑定局部变量对函数以外的任何内容均无任何影响。

尤其是,它对绑定到相同值的任何其他变量(或列表元素或其他对象的属性等)也没有影响,例如全局a。它们仍然是相同值的名称。

甚至还不清楚您正在尝试在这里做什么。您将a的类型更改为b的类型,就可以了。但是您还想做什么?

是否要将a更改为具有相同标识的对象b?如果是这样,则不需要任何方法。这就是a = b的意思。还是要成为一个不同的实例,但共享一个实例__dict__?还是要将所有b的属性复制到a中?浅还是深?是否应该删除周围有多余的属性a?您是否只关心存储在__dict__中的属性,还是需要例如__slots__才能工作?

无论如何,对于某些奇怪的用例,可能可能是合理的:

def change(self, other):
    inherited = dict(inspect.getmembers(self.__class__))
    for name, value in inspect.getmembers(self):
        if name not in inherited and not name.startswith('__'):
            delattr(self, name)
    self.__class__ = other.__class__
    inherited = dict(inspect.getmembers(other.__class__))
    for name, value in inspect.getmembers(other):
        if name not in inherited and not name.startswith('__'):
            setattr(self, name, value)

这对您的用例是否有用,我不知道。但这也许会让您对使用Python数据模型可以实际执行的操作有所了解。