В Python почему не работает импорт в exec в функции?
Я могу поместить оператор импорта в строку, выполнить его, и он работает (печатает случайную цифру):
code = """
import random
def f():
print random.randint(0,9)
"""
def f():
pass
exec code
f()
Теперь, если я поставлю exec code
а также f()
в своей собственной функции и вызвать его, это не работает.
def test():
exec code
f()
test()
Это говорит NameError: global name 'random' is not defined
, Есть идеи, что происходит? Спасибо
3 ответа
Здесь происходит то, что модуль random импортируется как локальная переменная в тесте. Попробуй это
def test():
exec code
print globals()
print locals()
f()
распечатает
{'code': '\nimport random\ndef f():\n print random.randint(0,9)\n', '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x02958BF0>, '__name__': '__main__', '__doc__': None}
{'random': <module 'random' from 'C:\Python27\lib\random.pyc'>, 'f': <function f at 0x0295A070>}
Причина f
не вижу random
в том, что f
не является вложенной функцией внутри test
- если вы сделали это:
def test():
import random
def f():
print random.randint(0,9)
f()
это будет работать. Однако вложенные функции требуют, чтобы внешняя функция содержала определение внутренней функции при компиляции внешней функции - это потому, что вам нужно установить переменные ячейки для хранения переменных, которые совместно используются двумя (внешними и внутренними) функциями.
Чтобы случайно попасть в глобальное пространство имен, вы просто должны сделать что-то вроде этого
exec code in globals(),globals()
Аргументы exec после in
Ключевое слово - это глобальное и локальное пространства имен, в которых выполняется код (и, следовательно, где хранится имя, определенное в коде exec'd).
Укажите, что вы хотите глобальный random
модуль
code = """
import random
def f():
global random
print random.randint(0,9)
"""
Проблема в том, что вы импортируете random
модуль в область вашей функции, а не глобальную область.