Ответ 1
Как насчет этого:
def test():
exec (code, globals())
f()
Я могу поместить оператор import в строку, выполнить его, и он работает (печатает случайную цифру):
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
.
Любая идея, что происходит?
Благодаря
Как насчет этого:
def test():
exec (code, globals())
f()
Что здесь происходит, так это то, что модуль 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
в область вашей функции, а не в глобальную область.