Python:在多层继承中更改对象类

0 投票
2 回答
1823 浏览
提问于 2025-04-17 04:23

我在这里看了很多问题,想找到解决我问题的答案,但都没有成功。可能是因为我不知道该用什么关键词去搜索。我的问题是这样的:

我有一个程序,它有多层继承结构,我正在尝试找出将一个对象的类更改为子类的最佳方法。假设我有以下代码:

class A(object):

    def __init(self, filename, ..)
        super(A, self).__init__()
        ...some assignments here

class B(A):

    def __init(self, filename, ..)
        super(B, self).__init__()
        ...some assignments here

class C(A):

    def __init(self, filename, ..)
        super(C, self).__init__()
        ...some assignments here

等等...
我总是想先初始化一个A类的对象。根据使用的文件类型,赋值可能会有所不同,而根据这些赋值,我可以判断文件的类型。所以现在我想把这个对象的类改成合适的类。

我知道我可以把A对象传给B或C,然后使用复制或深复制,但在A中,我有一个对象的引用是不能改变的,还有一些是可以改变的。此外,在初始化B或C之后,我还需要删除A中的那个对象。

class B(A):

    def __init__(self, filename, objA = None):
        if objA is not None:
            self.__dict__ = copy.deepcopy(objA.__dict__)
            del(objA)
        else:
            super(B, self).__init__(filename)

还有另一种可能性,就是把_class属性改成另一个类,然后使用新类的某种更新方法。
我想知道,这两种方法哪种更推荐,或者有没有更好的方法。谢谢!

2 个回答

1

这段代码会解释你想要做的事情

class B(object):
    def x(self):
        print 'b'

class A(object):
    def x(self):
        print 'a'

现在我们创建两个对象

a = a()
b = b()

a.x()
a

b.x()
b

如果你想让'a'变成一个B类的对象

 a.__class__ = type(b)

或者

 a.__class__ = B

现在x这个属性是来自B类的。

 a.x()
 b
3

你想要的是一个工厂:一个函数,它打开文件,读取必要的信息来判断这个文件是什么类型,然后初始化并返回一个合适的对象。

如果你想保持它是一个类,你需要重写 __new__() 方法,然后返回一个你想要的类的对象,而不是返回它自己的类。(你也可以使用元类,通过重写 __call__() 来实现。)

你也可以在创建实例后,改变这个实例的类,只需把它的 __class__ 属性改成你想要的类。这样做是可行的,但工厂方法会让其他阅读你代码的程序员更容易理解。

撰写回答