2017-03-20 7 views
0

、コードのこの部分が表示されますのPython 3.4、Execで作成された変数へのアクセスもない()

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変数を作成するのを期待しています。この変数には、ローカルで返された辞書を示すような期待値(['一般情報'、 '実験パラメータ'、 '計算パラメータ' )。しかし、このkeys2変数にアクセスすることはできません(名前 'keys2'は定義されていません!!!!)。どうして ?


EDIT 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'] 

BUT !!!なぜ私は上記のコードを変更した場合:

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 

EDIT 2:我々は再びNameError例外が発生して見ることができるようにkeys2変数は、作成されていない

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) 

続けることによって...)(のexec()や地元の人々と遊ぶことは、コードのフォローピースを考慮します。

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) 

出力は次のとおりです。私は辞書(名前空間)(Execで引数として渡されたことを理解し、この結果

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()の実行後に作成された変数。これは理解されていますが、EDIT 1ではなぜkeys2 = locals()['keys2']が動作していないのですか?keys2 = namespace ['keys2']はこのEDIT 2で動作していますか?


EDIT 3:

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()や地元の人々()でプレーを続けることで...コードのフォローピースを考慮しますだから、exec()関数のグローバル変数としてkeys2を定義しても、exec()関数の後にglobals()を返すのはグローバルスコープではありません。 ..

+1

[docs for 'locals'](https://docs.python.org/3/library/functions.html#locals)には、この辞書の内容を変更しないでください;変更はインタープリタによって使用されるローカル変数とフリー変数の値に影響を及ぼさないかもしれません。しかし、とにかく 'exec'を使うことはほとんどありません。あなたは何を達成しようとしていますか?これはXY問題のように聞こえます。 –

+0

あなたのコードは 'key2 = list(dico [ans])'を実行しますか?なぜそれをやるだけではないのですか?また、文字列の 'format'メソッドについて学ぶことで利益を得ることができます。 – jsbueno

+0

Rmk 1:私が以前に知りませんでしたxyの問題のコンセプトをありがとう!!!私は大規模なsrcipt(私は完全にここで再現することはできません!)、辞書の辞書に入る前に、どこに私がわからない場所に私が必要なので、私のケースではexecを使用する必要があると思う([x]、dico ['toto'] ['titi'] [['tata'] ['tete']、4 [x])、各レベルのキーは何ですか(xの値) 。 – servoz

答えて

1

exec documentation for Python 3に記載されるように:

注:機能地元の人々のために記載したように、デフォルトの地元の人々は、下に)(動作:デフォルトの地元の辞書への変更が試みられるべきではありません。関数exec()が復帰した後、地方のコードの効果を見る必要がある場合は、明示的な現地辞書を渡してください。

あなたは完全に試みを無視するのPython 3.ローカル変数の参照にexecを持つ新しいローカル変数を作成することはできません。

+0

新しい*グローバル*変数を作成できます。 –

+0

私が上記のコメントで言ったように、私は地元の人とグローバルを理解していない可能性があります。そして、それらとexec()の間の相互作用かもしれません...時には深さが私たちは先験的に何を考えているのですか?すべてのあなたのコメントと答えに感謝!私は今これをすべて消化する必要があります...そして私は解決策...または新しい愚かな質問に戻って行きます:-)) – servoz

関連する問題