使用Python 3.4并在函数中,这段代码出现:
ch0 = 'dico[\''+ ans +'\']' # dico is a dictionary and ans is a key of this dictionary
print('test')
print(list(locals()))
exec('keys2 = list(' + ch0 + ')', locals())
print(list(locals()))
print(locals()['keys2'])
print('keys2:', keys2)
这是输出:
test
['dico', 'save', 'keys0', 'LOG_FILENAME', 'ch0', 'flag', 'completer', 'k', 'ans', 'keys1']
['dico', 'save', 'keys0', 'LOG_FILENAME', 'ch0', 'flag', 'completer', 'k', 'ans', 'keys1', '__builtins__', 'keys2']
['General informations', 'Experiments parameters', 'Calculated parameters']
Traceback (most recent call last):
File "/data_1/dataGestion.py", line 189, in consult_db
print('keys2:', keys2)
NameError: name 'keys2' is not defined
正如预期的那样,我们观察到在本地范围内创建了keys2变量,并且该变量包含了预期的值(['一般信息','实验参数',&# 39;计算参数'])似乎表示locals()返回的字典。但是无法访问此keys2变量(名称' keys2'未定义!!!!)。为什么?
编辑1:我们看到Keys2在本地范围内,因为在上述问题的代码中:
print(list(locals()))
和
print(locals()['keys2'])
返回:
['dico', 'keys0', 'save', 'k', 'ans', 'keys1', '__builtins__', 'flag', 'LOG_FILENAME', 'keys2', 'ch0', 'completer']
['General informations', 'Experiments parameters', 'Calculated parameters']
但是!!!为什么我用以下代码更改上面的代码:
ch0 = 'dico[\''+ ans +'\']' # dico is a dictionary and ans is a key of this dictionary
print('test')
exec('keys2 = list(' + ch0 + ')', locals())
keys2 = locals()['keys2']
print('keys2:', keys2)
未创建keys2变量,因为我们再次看到引发的NameError异常:
Traceback (most recent call last):
File "/data_1/IRM/amigo/src/IRMAGE_python_modules/IRMAGE_dataGestion.py", line 191, in consult_db
print('keys2:', keys2)
NameError: name 'keys2' is not defined
编辑2:继续玩exec()和locals()......考虑以下代码:
ch0 = 'dico[\''+ ans +'\']' # dico is a dictionary and ans is a key of this dictionary
print('test')
namespace = locals()
print(list(namespace))
print(list(locals()))
print(list(globals()))
exec('keys2 = list(' + ch0 + ')', namespace)
keys2 = namespace['keys2']
print()
print(list(namespace))
print(list(locals()))
print(list(globals()))
print('keys2:', keys2)
输出结果为:
test
['ch0', 'ans', 'completer', 'save', 'keys0', 'keys1', 'k', 'flag', 'dico', 'LOG_FILENAME']
['ch0', 'ans', 'completer', 'save', 'keys0', 'keys1', 'k', 'flag', 'dico', 'LOG_FILENAME', 'namespace']
['__spec__', 'nbLigne', 'remove', 'listdir', 'getSampleStyleSheet', 'Paragraph', '__builtins__', 'system', 'upvivification', '__package__', 'exit', '__doc__', 'AutoVivification', 'recupParameter', 'verSofts', 'logging', 'revivification', 'renameComment', 'unvivification', 'creatExpParameter', 'rlcompleter', 'consult_db', 'makedirs', 'datetime', 'isdir', 'recupCover', 'MyCompleter', 'verifFichier', 'dico2txt', 'para2dic', 'readlineComp', '__name__', '__file__', 'anonym', '__cached__', '__loader__']
['ch0', 'ans', 'completer', 'save', 'keys0', 'keys1', 'k', 'flag', 'dico', 'LOG_FILENAME', 'namespace', '__builtins__', 'keys2']
['ch0', 'ans', 'completer', 'save', 'keys0', 'keys1', 'k', 'flag', 'dico', 'LOG_FILENAME', 'namespace', '__builtins__', 'keys2']
['__spec__', 'nbLigne', 'remove', 'listdir', 'getSampleStyleSheet', 'Paragraph', '__builtins__', 'system', 'upvivification', '__package__', 'exit', '__doc__', 'AutoVivification', 'recupParameter', 'verSofts', 'logging', 'revivification', 'renameComment', 'unvivification', 'creatExpParameter', 'rlcompleter', 'consult_db', 'makedirs', 'datetime', 'isdir', 'recupCover', 'MyCompleter', 'verifFichier', 'dico2txt', 'para2dic', 'readlineComp', '__name__', '__file__', 'anonym', '__cached__', '__loader__']
keys2: ['Calculated parameters', 'General informations', 'Experiments parameters']
通过这个结果,我理解使用exec()作为参数传递的字典(命名空间)用于查找函数exec()范围内的变量,但是这个字典(命名空间)包含之后创建的所有变量执行exec()。这是理解的,但我还没有理解为什么在编辑1中,keys2 = locals()[' keys2']不起作用而keys2 = namespace [' keys2']工作正常在这个编辑2?
编辑3:继续玩exec()和locals()......考虑以下代码:
ch0 = 'dico[\''+ ans +'\']' # dico is a dictionary and ans is a key of this dictionary
print('test')
print(list(locals()))
print(list(globals()))
exec("global keys2; keys2 = list(" + ch0 + "); print('\\n** keys2 inside exec function: {}'.format(keys2))", locals())
print()
print(list(locals()))
print(list(globals()))
print('keys2:', keys2)
输出结果为:
test
['ch0', 'LOG_FILENAME', 'k', 'flag', 'save', 'ans', 'keys0', 'dico', 'completer', 'keys1']
['recupCover', 'MyCompleter', '__name__', 'para2dic', 'readlineComp', 'upvivification', 'listdir', 'verifFichier', 'recupParameter', 'system', 'remove', '__doc__', 'nbLigne', 'renameComment', '__spec__', '__file__', 'anonym', 'creatExpParameter', '__package__', 'isdir', 'revivification', 'exit', '__loader__', 'makedirs', 'datetime', 'consult_db', 'Paragraph', '__cached__', '__builtins__', 'AutoVivification', 'getSampleStyleSheet', 'unvivification', 'rlcompleter', 'logging', 'verSofts', 'dico2txt']
** keys2 inside exec function: ['Experiments parameters', 'Calculated parameters', 'General informations']
['ch0', 'LOG_FILENAME', 'k', 'flag', 'save', 'ans', 'keys0', 'dico', 'completer', 'keys1', '__builtins__', 'keys2']
['recupCover', 'MyCompleter', '__name__', 'para2dic', 'readlineComp', 'upvivification', 'listdir', 'verifFichier', 'recupParameter', 'system', 'remove', '__doc__', 'nbLigne', 'renameComment', '__spec__', '__file__', 'anonym', 'creatExpParameter', '__package__', 'isdir', 'revivification', 'exit', '__loader__', 'makedirs', 'datetime', 'consult_db', 'Paragraph', '__cached__', '__builtins__', 'AutoVivification', 'getSampleStyleSheet', 'unvivification', 'rlcompleter', 'logging', 'verSofts', 'dico2txt']
Traceback (most recent call last):
File "/data_1/IRM/amigo/src/IRMAGE_python_modules/IRMAGE_dataGestion.py", line 206, in consult_db
print('keys2:', keys2)
NameError: name 'keys2' is not defined
所以......即使我们在exec()函数中将keys2定义为全局变量,它也不在全局范围内,因为在exec()函数之后返回globals()...我承认有些事情想念我......
答案 0 :(得分:2)
如exec
documentation for Python 3中所述:
注意:默认的locals的行为与下面的函数locals()相同:不应尝试修改默认的locals字典。如果您需要在函数exec()返回后查看代码对locals的影响,则传递显式的locals字典。
您无法在Python 3上使用exec
创建新的局部变量。局部变量查找完全忽略了尝试。