Python 3.4,无法访问使用exec()

时间:2017-03-20 18:50:26

标签: python

使用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()...我承认有些事情想念我......

1 个答案:

答案 0 :(得分:2)

exec documentation for Python 3中所述:

  

注意:默认的locals的行为与下面的函数locals()相同:不应尝试修改默认的locals字典。如果您需要在函数exec()返回后查看代码对locals的影响,则传递显式的locals字典。

您无法在Python 3上使用exec创建新的局部变量。局部变量查找完全忽略了尝试。