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

Python 如何在函数中动态生成子类?,python,oop,Python,Oop,我试图编写一个函数,创建一个名为的新子类,该子类使用作为参数传递的字符串命名。我不知道什么工具最适合这样做,但我在下面的代码中尝试了一下,只创建了一个名为“x”的子类,而不是预期的“MySubClass”。如何正确编写此函数 class MySuperClass: def __init__(self,attribute1): self.attribute1 = attribute1 def makeNewClass(x): class x(MySuperClas

我试图编写一个函数,创建一个名为的新子类,该子类使用作为参数传递的字符串命名。我不知道什么工具最适合这样做,但我在下面的代码中尝试了一下,只创建了一个名为“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)

最安全、最简单的方法是使用
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})

Ryan的答案是完整的,但我认为值得注意的是,除了使用内置的
type
exec
/
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
的实例时使用字符串,因此此方法是完全动态的。

使用
类型
内置函数。它是类语句的动态形式。您可以传入一个字符串名作为第一个参数,基类作为第二个参数,命名空间dict作为第三个参数。您必须使用Python。起初我犯了一些语法错误,但一旦我解决了这些错误,您的代码就工作了。谢谢我还在努力弄清楚这到底是怎么回事。我什么都懂,除了带局部变量的部分()。函数的locals()不是返回给定函数中局部变量的字典吗?你用什么符号来表示locals()['y']()?这看起来像是对两个函数调用之间的列表项的引用。请解释一下,这样我也能理解黑色魔法。@user3150635['Y']部分不用于引用列表。Python中的列表只能有整数索引。另一方面,字典可以将整数、字符串和正确实现哈希接口的任何其他内容作为有效键。你是对的,locals()返回一个字典,然后我获取该字典并访问键“Y”的值,我们之前在前一行中将其设置为类Y的值。最后,我用最后一组括号实例化该类。