为什么PythonExec定义类不起作用

为什么PythonExec定义类不起作用,python,class,exec,Python,Class,Exec,下面是代码,在_getestobj()中创建演示实例时,exec定义的类“demo”不起作用 文件名:test.py class runOneIni(): def _getTestObj(self): demo(self.tcName,secSetup,doc) def start(): #implicit define 'demo' class by exec is not working, get error in runOneIni->_g

下面是代码,在_getestobj()中创建演示实例时,exec定义的类“demo”不起作用

文件名:test.py

class runOneIni():
    def _getTestObj(self):
        demo(self.tcName,secSetup,doc)



def start():   
    #implicit define 'demo' class by exec is not working, get error in runOneIni->_getTestObj, Error is :
    #  NameError: name 'demo' is not defined
    a='global demo'
    exec(a)

    str="class demo(tInvokeMethod.tInvokeMethod): pass'
    exec(str)

    #Explict define demo class is working
    #global demo
    #class demo(tInvokeMethod.tInvokeMethod): pass


if __name__ == '__main__':
    start()    
(1) 您有一个未终止的字符串


(2) 无需使用
exec
执行此操作<代码>类本身就是一个可执行语句,它可以出现在任何其他语句可以出现的任何地方(需要表达式语句的地方除外)。

问题不在于通过exec定义类。按计划进行以下工作:

exec 'class hi: pass'
您的问题是exec语句内部的“全局”在其外部没有效果。根据exec的python文档:

global是解析器的一个指令。它仅适用于与全局语句同时解析的代码。特别是,exec语句中包含的全局语句不会影响包含exec语句的代码块,并且exec语句中包含的代码不受包含exec语句的代码中的全局语句的影响


你为什么这么做?(高管除外)
你为什么要用
exec

此外,使用
exec
执行此操作将:

  • 不工作
  • python-2.x
    python-3.x
    中给出不同的结果
  • 例如:

    class demo:
        a = 'a'
    
    print(demo.a)
    
    def start():
        global demo
        class demo: b = "b"
    
        try:
            print(demo.a)
        except AttributeError:
            print(demo.b)
    
    if __name__ == '__main__':
        start()
    
        try:
            print(demo.a)
        except AttributeError:
            print(demo.b)
    
    python-2.x
    python-3.x
    中将给出:

    a
    b
    b
    
    现在让我们用
    exec
    试试:

    class demo:
        a = 'a'
    
    print(demo.a)
    
    def start():
        exec('global demo', globals(), locals())
    
        exec('class demo: b = "b"', globals(), locals())
    
        try:
            print(demo.a)
        except AttributeError:
            print(demo.b)
    
    if __name__ == '__main__':
        start()
    
        try:
            print(demo.a)
        except AttributeError:
            print(demo.b)
    
    输出
    python2.7

    a
    b
    a
    
    输出
    python3.2

    a
    a
    a
    

    Q:如何“动态创建类”?

    正如kindall已经告诉您的,
    exec
    不是这样做的方法


    A或A可以这样做,但你确定你真的需要吗?

    你可以这样做:

    class SomeBaseClass(object):
        def __init__(self):
            self.a = 1
            self.b = 2
    
    def make_new_class(name):
        class TemplateClass(SomeBaseClass):
            def __init__(self):
                SomeBaseClass.__init__(self)
                self.a = 3
        return type(name, (TemplateClass,), {})
    
    o1 = SomeBaseClass()
    print o1.a, o1.b
    
    NewClass = make_new_class('NewClass')
    o2 = NewClass()
    print o2.a, o2.b
    
    结果:

    1 2
    3 2
    

    我可能会晚一点去参加聚会,但我想出了一些似乎很有效的办法。由于setting属性,它甚至会更正类型

    我相信这一切都是非常不和谐的,但我觉得这很有趣

    def generateClass(propertyNames,propertyTypes):
    
    
        string = 'class generatedClass(object):\n    def __init__(self):\n'
    
        for pN in propertyNames:
            string += '        self._m' + pN + ' = None\n'
    
    
        string += '    \n    \n'
    
        i = 0
        for pN in propertyNames:
            string += '    @property\n' \
                '    def ' + pN + '(self):\n' \
                '        return self._m' + pN + '\n' \
                '    @' + pN + '.setter' +'\n' \
                '    def ' + pN + '(self,a'+ pN + '):\n' \
                '        if a' + pN + ':\n'\
                '            self._m'+ pN + ' = ' + propertyTypes[i] + '(a' + pN + ')\n'\
                '        \n'
            i += 1
    
        exec(string)
        return generatedClass()
    
    if __name__ == '__main__':
        c = generateClass(['SomePropertyName'],['str'])
        print c.__dict__
        setattr(c,'SomePropertyName','some string')
        print c.__dict__
    

    我想做的是动态创建类,在这个例子中是名为“demo”的类,但是类名不是固定的,它是可变的。所以我的想法是使用string来组装create class语句,exec就是string。那么,动态地创建类,您几乎不需要
    exec
    来完成这项工作!如何“动态创建类”?@brike:你确定你真的需要它吗?无论如何,
    exec
    不是这样做的。