Как именно eval и exec взаимодействуют с __future__? - PullRequest
0 голосов
/ 28 апреля 2018

Я хочу знать, как __future__ импорт взаимодействует с eval и execcompile, я полагаю).

Эксперимент (с python 2) показывает, что импорт на уровне модуля __future__ влияет на код, выполняемый eval и exec:

from __future__ import print_function

print(1, end='!\n')
eval(r"print(2, end='!\n')")
exec r"print(3, end='!\n')"

Выход:

1!
2!
3!

Но в то же время код, выполняемый с помощью exec, может выполнять собственный импорт __future__, который влияет только на код локально:

print 1
exec r"from __future__ import print_function; print(2, end='!\n')"
print 3
exec r"print 4"

Выход:

1
2!
3
4

Но экспериментирование может только дать вам так далеко. Мои вопросы:

  • Являются ли эти взаимодействия четко определенными и задокументированными?
  • Есть ли способ отключить на уровне модуля __future__ импорт в eval, exec и compile?

1 Ответ

0 голосов
/ 28 апреля 2018

за справочник по языку :

Код, скомпилированный при вызове встроенных функций exec() и compile() которые происходят в модуле M, содержащем будущее заявление, будут по умолчанию используйте новый синтаксис или семантику, связанную с будущим заявление.

Вы можете отключить это поведение в compile:

Необязательные аргументы flags и dont_inherit определяют, какое будущее операторы (см. PEP 236 ) влияют на компиляцию source .

Например:

>>> from __future__ import print_function
>>> print('foo', 'bar')
foo bar
>>> code1 = compile("print('foo', 'bar')", "<string>", "exec")
>>> exec(code1)
foo bar
>>> code2 = compile("print('foo', 'bar')", "<string>", "exec", dont_inherit=True)
>>> exec(code2)
('foo', 'bar')

И наоборот, отключение использования импорта __future__ в произвольном коде, выполняемом / компилируемом, насколько я знаю, невозможно.

...