Следующий код дает различный вывод в Python2
и в Python3
:
from sys import version
print(version)
def execute(a, st):
b = 42
exec("b = {}\nprint('b:', b)".format(st))
print(b)
a = 1.
execute(a, "1.E6*a")
Python2
Отпечатки:
2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)]
('b:', 1000000.0)
1000000.0
Python3
Отпечатки:
3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)]
b: 1000000.0
42
Почему Python2
привязывает переменную b
внутри функции execute
к значениям в строке функции exec
, а Python3
не делает этого? Как я могу достичь поведения Python2
в Python3
? Я уже пытался передать словари для глобальных и локальных пользователей функции exec
в Python3
, но пока ничего не работало.
--- EDIT ---
После прочтения ответа Martijns я дополнительно проанализировал это с помощью Python3
. В следующем примере я даю locals()
dictionay как d
- exec
, но d['b']
печатает что-то еще, чем просто печать b
.
from sys import version
print(version)
def execute(a, st):
b = 42
d = locals()
exec("b = {}\nprint('b:', b)".format(st), globals(), d)
print(b) # This prints 42
print(d['b']) # This prints 1000000.0
print(id(d) == id(locals())) # This prints True
a = 1.
execute(a, "1.E6*a")
3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)]
b: 1000000.0
42
1000000.0
True
Сравнение идентификаторов d
и locals()
показывает, что они являются одним и тем же объектом. Но в этих условиях b
должен быть таким же, как d['b']
. Что не так в моем примере?