Подтвердить что ты не робот

В Python, почему не работает импорт в exec в функции?

Я могу поместить оператор 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. Любая идея, что происходит? Благодаря

4b9b3361

Ответ 1

Как насчет этого:

def test():
    exec (code, globals())
    f()

Ответ 2

Что здесь происходит, так это то, что модуль 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).

Ответ 3

Укажите, что вы хотите глобальный random модуль

code = """
import random
def f():
  global random
  print random.randint(0,9)
"""

Проблема заключается в том, что вы импортируете модуль random в область вашей функции, а не в глобальную область.