这是代码,在_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()
答案 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
执行此操作:
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
问:如何“动态创建课程”?
由于 kindall 已经告诉过您,exec
不是这样做的。
metaclass或class 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__