【问题标题】:Dynamically creating classes with eval in python在python中使用eval动态创建类
【发布时间】:2013-01-09 18:27:38
【问题描述】:

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

class Int :
    def __init__(self,param) :
        self.value = 3

我正在这样做。

def makeClass( x ) :

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

然后调用

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

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

【问题讨论】:

    标签: python oop metaprogramming


    【解决方案1】:

    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.
    

    【讨论】:

    • 谢谢,那是新的。你能指出一个详细的例子吗?
    • @noPE -- 一个详细的例子?
    • 知道了。我猜我看不到你的完整回复。我的错。
    • @noPE——也许吧。我只是对其进行了编辑以使其更加冗长,希望能够澄清问题。
    • 这里是使用type动态创建类的更完整的解释:stackoverflow.com/a/6581949/298607
    【解决方案2】:

    根据要求,这适用于 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)
    

    如果您希望从现有类中添加方法:

    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)
    

    输出:

    3 True False
    3 True False
    

    减少打字带来的副作用:

    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)
    

    不过,Mgilson 的 type 答案可能是首选。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-24
      • 2012-11-15
      • 1970-01-01
      • 2017-10-05
      • 2018-05-16
      • 2012-01-08
      • 2015-11-22
      相关资源
      最近更新 更多