Python 如何从超类实例创建子类实例

Python 如何从超类实例创建子类实例,python,design-patterns,Python,Design Patterns,我想从Python中的超类实例创建一个子类实例。假设我有这样的东西: class A(): def __init__(self, type): ... self.type = type # this will be something that corresponds to either B or C class B(A): def do_something(): # this method is subclass specifi

我想从Python中的超类实例创建一个子类实例。假设我有这样的东西:

class A():
    def __init__(self, type):
        ...
        self.type = type # this will be something that corresponds to either B or C

class B(A):
    def do_something():
        # this method is subclass specific

class C(A):
    def do_something():
        # this method is again subclass specific
我有一个函数,它接收a的一个实例,我需要根据a的属性
type
创建B或C(或D…)的一个实例

我不知道该怎么办。有没有办法解决这个问题,或者解决方案需要重新设计


谢谢

使用从类型映射到类的字典

class A():
    typemap = {}

    def __init__(self, typearg): # renamed this argument so it doesn't shadow standard type() function
        self.type = typearg
        self.typemap[typearg] = type(self)

    def create_child(self, *args):
        return typemap[self.type](*args)
当构造函数运行时,
type(self)
获取所创建对象的子类。然后将其存储在字典中,因此我们可以使用
self.type
查找它


create\u child()
在字典中查找该类,并调用它来创建该子类的新实例。

首先重新定义类a、B和C,如下所示。注意,您还需要通过
super()将
type
值从子类传递到超类构造函数

然后创建另一个类,该类可以决定是否为您调用B和C,并将该对象保存在本地

class User:

    def __init__(self, type):
        self.obj = None
        if type == 'B':
            self.obj = B(type)
        elif type == 'C':
            self.obj = C(type)
然后您可以用不同的类型实例化用户类,并查看是否调用了正确的
do\u something

user_B = User('B')
user_B.obj.do_something()
#do_something called for B
user_C = User('C')
user_C.obj.do_something()
#do_something called for C

你应该研究工厂设计模式。
self.type
真的可以作为所需子类的引用吗?在我的例子中,它对应于但不是子类的引用,我无法更改。你的答案,无论多么简洁,对于一个刚刚开始掌握python的人来说,似乎过于超前和简洁。我建议对代码添加更多解释。@Barmar,谢谢您的回复。但是如果你能为我澄清一件事,如果我有一个
A()
的实例,并且我传入
typearg='B'
,那么类型映射将是
typemap={'B':type
,因此当调用
create\u child
方法时,它是否会返回
A
的实例而不是
B
?在
typearg
和实际类名之间没有内置关系,您可以在调用构造函数时创建关系。如果调用
A('foo'))
然后,当您调用
创建\u child('foo')时
您得到了
A
的一个实例。问题只是说type参数对应于
A
B
,它不必是实际的名称。感谢您提供了清晰的解决方案。我希望避免创建另一个类来根据类型实例化正确的对象,但我可能不得不按照您的要求去做很好,如果答案对你有帮助,请投票/接受
user_B = User('B')
user_B.obj.do_something()
#do_something called for B
user_C = User('C')
user_C.obj.do_something()
#do_something called for C