在Python中从文件动态创建类

jiv*_*key 5 python

我已经看到了这些"动态创建类"的问题,这些问题的答案是"使用type()函数".我相信我必须在某个时候,但是知道我是无能为力的.但是从我所看到的你已经知道了关于这个课程的一些知识,比如一个名字.

我要做的是解析一个idl类型的文件,并从中创建一个具有方法和属性的类.所以在解析字符串之前,我没有知道类名,函数,参数或任何内容.

有任何想法吗?

nin*_*cko 14

http://docs.python.org/library/functions.html#type

谷歌有点难,但你可以搜索python type(name, bases, dict) function examples得到:

http://www.voidspace.org.uk/python/articles/metaclasses.shtml

以上摘录,深入探讨了问题的核心:


以下几乎是等价的:

def __init__(self, x):
    self.x = x

def printX(self):
    print self.x

Test = type('Test', (object,), {'__init__': __init__, 'printX': printX})
Run Code Online (Sandbox Code Playgroud)

和:

class Test(object):
    def __init__(self, x):
        self.x = x

    def printX(self):
        print self.x
Run Code Online (Sandbox Code Playgroud)

有两种方法可以动态创建我能想到的功能.通常糟糕的方法是编写代码并重新解析它(尽管正确完成,这可以大大提高性能).理智的方法是实现一个解释你的IDL的功能.这被称为高阶函数:http://effbot.org/pyfaq/how-do-you-make-a-higher-order-function-in-python.htm

如果您找不到IDL的解释器(如果它是自定义IDL),那么您要编写的内容的示例就像上面的链接,例如:

def makeMethod(idlCode):
    syntax = MyIDL.parse(idlCode)

    def newMethod(*args, **kw):
        if syntax.statementType == MyIDL.IF_STATEMENT:
            if secureLookup(mySyntaxTree.IF):
               return secureLookup(args[0]) 
            else:
               return secureLookup(args[1])
        ...

    return (syntax.methodName, newMethod)
Run Code Online (Sandbox Code Playgroud)

如果你在IDL的结构和*args和**kw的语法之间建立一个映射,有很多更优雅的方法来扩展这个方法,但这给你最大的灵活性,是我能做到的最简单和最基本的方法考虑到.

然后你会传入:

class DynamicIdlClass(object):
    ...

for idlObject in idlCode:
    methods = dict(makeMethod(clause) for clause in idlObject.clauses})
    methods['__init__'] = makeInitMethod(idlObject.initClause)
    idlObject = type('Test', (DynamicIdlClass,), methods)

    yield idlObject  # or idlObjectsList.push(idlObject), etc.
Run Code Online (Sandbox Code Playgroud)