Невозможно найти функции, определенные в динамически загружаемом модуле
Я очень новичок в питоне. Вот проблема, с которой я столкнулся. Я подключил встроенный._import_ к своему пользовательскому обработчику, который загружает модуль из строки.
def import_hook(name, globals=None, locals=None, fromlist=None):
if name in sys.modules:
obj = sys.modules[name]
return obj
#Make sure we hook only for modules which start with ajay
if name.startswith("ajay"):
statement = '''
print 'inside the ajay module'
def ajay_func():
print 'inside the func'
'''
mod = imp.new_module(name)
mod.__file__ = name
compiled = compile(statement, '<string>', 'exec')
exec compiled in mod.__dict__
sys.modules[name] = mod
return mod
return original_import(name, globals, locals, fromlist)
Затем я использую эту функцию в функции, которая загружает модуль и вызывает его функцию в операторе exec.
original_import = __builtin__.__import__
def test(request):
statement = '''
import sys
import ajay
def ILessons_1(request):
ajay.ajay_func()
'''
try:
__builtin__.__import__ = import_hook
compiled = compile(statement, '<string>', 'exec')
exec (compiled, globals(), locals()) #in statement_module.__dict__
ajay.ajay_func()
return ILessons_1(request);
finally:
__builtin__.__import__ = original_import
pass
Когда я запускаю этот код, я получаю сообщение об ошибке "глобальное имя" ajay "не определено" в строке "return ILessons_1(request);". Интересно, что Python может разрешить Ajay в строке чуть выше этой строки. Я почти уверен, что допустил ошибку в заявлении exec, но не смог понять.
Может кто-нибудь, пожалуйста, помогите мне решить эту проблему. Спасибо
1 ответ
Отметил несколько вопросов здесь:
1) globals
а также locals
являются встроенными именами функций, вы не должны использовать их в качестве имен переменных.
2) Возможно, ошибка? (протестировано с python 2.7.1 под Ubuntu)
Рассмотрим следующий код (обратите внимание на выражение exec):
def outer_function():
foo = "foobar"
statement = '''
def inner_function():
print foo
'''
#exec statement in globals(), locals()
exec statement in globals().update(locals())
inner_function()
outer_function()
Здесь закомментированная строка (exec с 2 аргументами после in) не будет работать так, как описано в документации, и приведет к:
NameError: global name 'foo' is not defined
Но можно вручную объединить глобальные и локальные переменные и передать их в exec (следующая строка после комментария в моем примере). Выглядит как обходной путь для меня.