如何在函数中动态生成子类?

时间:2015-03-28 19:39:30

标签: python oop

我正在尝试编写一个函数,该函数创建一个以其作为参数传递的字符串命名的新子类。我不知道哪种工具最适合这个,但我在下面的代码中给了它一个镜头,并且只设法创建一个名为“x”的子类,而不是按照预期的“MySubClass”。如何正确编写此功能?

class MySuperClass:
    def __init__(self,attribute1):
        self.attribute1 = attribute1

def makeNewClass(x):
    class x(MySuperClass):
        def __init__(self,attribute1,attribute2):
            self.attribute2 = attribute2

x = "MySubClass"
makeNewClass(x)
myInstance = MySubClass(1,2)

2 个答案:

答案 0 :(得分:1)

最安全,最简单的方法是使用type内置函数。这需要一个可选的第二个参数(基类的元组)和第三个参数(函数的dict)。我的建议如下:

def makeNewClass(x):
    def init(self,attribute1,attribute2):
        # make sure you call the base class constructor here 
        self.attribute2 = attribute2

    # make a new type and return it
    return type(x, (MySuperClass,), {'__init__': init})

x = "MySubClass"
MySubClass = makeNewClass(x)

您需要使用您希望新类具有的所有内容填充第三个参数的dict。您很可能正在生成类,并且希望将它们推回到列表中,其中名称实际上并不重要。我不知道你的用例。


或者您可以访问globals并将新类放入其中。这是一种非常奇怪的动态生成类的方法,但这是我能想到的最好的方式来获得你想要的东西。

def makeNewClass(x):
    def init(self,attribute1,attribute2):
        # make sure you call the base class constructor here 
        self.attribute2 = attribute2

    globals()[x] = type(x, (MySuperClass,), {'__init__': init})

答案 1 :(得分:0)

Ryan的答案已经完成,但我认为除了使用内置的typeexec之外,还有至少另外一种邪恶的方法可以做到这一点。 / eval或其他:

class X:
    attr1 = 'some attribute'

    def __init__(self):
        print 'within constructor'

    def another_method(self):
        print 'hey, im another method'

# black magics
X.__name__ = 'Y'
locals()['Y'] = X
del X

# using our class
y = locals()['Y']()
print y.attr1
y.another_method()

请注意,我在创建类Y时和初始化Y的实例时只使用了字符串,因此此方法是完全动态的。