Posted at

[python] 文を実行するexec, eval

More than 3 years have passed since last update.


exec

2. 組み込み関数


exec(object[, globals[, locals]])

この関数は Python コードの動的な実行をサポートします。 object は文字列かコードオブジェクトでなければなりません。文字列なら、その文字列は一連の Python 文として解析され、そして (構文エラーが生じない限り) 実行されます。

オプションの部分が省略されると、コードは現在のスコープ内で実行されます。


で、ここでは、objectに文字列を入れて使います。


eval


eval(expression, globals=None, locals=None)

文字列とオプションの引数 globals 、 locals をとります。 globals を与える場合は辞書でなくてはなりません。 locals を与える場合は任意のマッピングオブジェクトにできます。

expression 引数は Python 式 (技術的にいうと、条件のリスト) として解析され評価されます。このとき辞書 globals および locals はそれぞれグローバルおよびローカルな名前空間として使われます。



使い方


sample_exec.py

Python 3.5.0

>>> exec("a = 10; b = 13; print(a, b)")
10 13
>>> print(a, b)
10 13
>>> eval(`a + b`)
23

ここでは、execでa = 10, b = 13, print(a, b)を実行しています。

evalは、a + bを実行して、その値を返しています。

また、globals()は、辞書なので、引数に辞書を与えればそこに書き込んでくれます。


use_dict.py

Python 3.5.0

>>> a = dict()
>>> exec("b = 1; c = 2", globals(), a)
>>> a
{'b': 1, 'c': 2}
>>> eval("b + c", a)
3

execでは、空のdictのaを{'b': 1, 'c': 2}としています。

evalでは、globalsをaとして、辞書a内の値で計算しています。なので、実際は、a['b'] + a['c']を計算しています。

これを使って、'json.loads' 的な使い方をしてみる。


json_like.py

# exec

''' write file '''
a = [1,2,3,4,5,6]
b = [2,3,4,5,6,7]
with open('test.txt', 'w') as fout:
fout.write('num_list_a = ' + repr(a))
fout.write('num_list_b = ' + repr(b))

''' load file '''
exec(open('test.txt').read())
print('a =', num_list_a, '\nb =', num_list_b)

# eval
''' write file '''
a = [1,2,3,4,5]
with open('test2.txt', 'w') as fout:
fout.write(repr(a))
del a

''' load file'''
num_list_c = eval(open('test2.txt').read())
print('c =', num_list_c)



出力


output.txt

a = [1, 2, 3, 4, 5, 6] 

b = [2, 3, 4, 5, 6, 7]
c = [1, 2, 3, 4, 5]

execでは値を返してくれないので、文字列で変数の定義をしなければなりません。

evalを使った場合には、値を返してくれますので簡単なものならばjson的な使い方ができます。


まとめ

execでpython文の実行

evalで単一の式評価