为什么python exec定义类不工作

时间:2012-02-20 14:51:35

标签: python class exec

这是代码,在_getTestObj()中创建演示实例时,exec定义的类'demo'不起作用。

FileName: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()    

5 个答案:

答案 0 :(得分:1)

(1)你有一个未终止的字符串

(2)没有必要使用exec来执行此操作。 class本身是一个可执行语句,可以出现在任何其他语句的任何位置(除了需要表达式语句的地方)。

答案 1 :(得分:0)

问题不在于通过exec定义类。以下按预期工作:

exec 'class hi: pass'

你的问题是exec语句中的“global”在它之外没有任何影响。根据exec的python文档:

  

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

答案 2 :(得分:0)

你为什么这样做? (exec apart)
为什么要尝试使用exec

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

  1. 不行。
  2. python-2.xpython-3.x中提供不同的结果。
  3. 示例:

    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.xpython-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
    

    问:如何“动态创建课程”?

    由于 kindall 已经告诉过您,exec不是这样做的。

    metaclassclass factory会这样做,但您确定确实需要吗?

答案 3 :(得分:0)

你可以这样做:

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

答案 4 :(得分:0)

我可能会迟到一点,但我想出了一些看似合适的东西。由于设置属性,它甚至会更正类型。

我确信这一切都非常令人讨厌,但我认为这很有趣。

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__