在python中使用eval动态创建类

noP*_*oPE 4 python oop metaprogramming

我想接受一个参数并创建一个名称为参数本身的类。例如,我以“Int”为参数,创建了一个名为“Int”的类,我的类就是这样的。

class Int :
    def __init__(self,param) :
        self.value = 3
Run Code Online (Sandbox Code Playgroud)

我就是这样做的。

def makeClass( x ) :

    return eval( 'class %s :\n    def __init__(self,param) :\n        self.type = 3'%(x,))
Run Code Online (Sandbox Code Playgroud)

然后打电话

myClass = makeClass('Int')
myInt = myClass(3)
Run Code Online (Sandbox Code Playgroud)

我收到了一个语法错误。请帮忙。

mgi*_*son 6

eval用于评估表达式,class不是表达式,而是语句。也许你想要这样的东西exec

附带说明一下,您在这里所做的事情可能很容易使用 完成type,然后您回避了使用eval/ 的所有性能和安全影响exec

def cls_init(self,param):
    self.type = 3

Int = type("Int",(object,),{'__init__':cls_init})
#           ^class name
#                ^class bases -- inherit from object.  It's a good idea :-)
#                           ^class dictionary.  This is where you add methods or class attributes.
Run Code Online (Sandbox Code Playgroud)


Cee*_*man 5

根据要求,这适用于 Python 2.7 和 Python 3.4,打印3

def makeClass(x):
    exec('class %s:\n\tdef __init__(self,v):\n\t\tself.value = v' % x)
    return eval('%s' % x)

myClass = makeClass('Int')
myInt = myClass(3)

print(myInt.value)
Run Code Online (Sandbox Code Playgroud)

如果您想从现有类添加方法:

def makeClass(name):
    parent = name.lower()
    exec('class %s(%s):\n\tdef __init__(self,v):\n\t\tself.value = v' % (name, parent))
    return eval('%s' % name)

Int = makeClass('Int')
myInt = Int(3)

Str = makeClass('Str')
myStr = Str(3)

print(myInt.value, myInt == 3, myInt == 5)
print(myStr.value, myStr == '3', myStr == 3)
Run Code Online (Sandbox Code Playgroud)

输出:

3 True False
3 True False
Run Code Online (Sandbox Code Playgroud)

减少打字带来的副作用:

def makeClass(name):
    parent = name.lower()
    exec('global %s\nclass %s(%s):\n\tdef __init__(self,v):\n\t\tself.value = v' % (name, name, parent))

makeClass('Int')
myInt = Int(3)

makeClass('Str')
myStr = Str(3)
Run Code Online (Sandbox Code Playgroud)

不过,米吉尔森的type答案可能是首选。