Невозможно найти функции, определенные в динамически загружаемом модуле - PullRequest
0 голосов
/ 23 января 2012

Я очень плохо знаком с Python.Вот проблема, с которой я столкнулся.Я подключил встроенный ._ 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 Ответ

0 голосов
/ 23 января 2012

Здесь замечено несколько проблем:

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 аргументами после в ) не будет работать, как описано в в документации , и приведет к:

NameError: global name 'foo' is not defined

Но можно вручную объединить глобальные и локальные объекты и передать их в exec (следующая строка после комментария в моем примере).Выглядит как обходной путь для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...