无法找到动态加载模块中定义的函数

时间:2012-01-23 07:42:12

标签: python import-hooks

我对python很新。这是我有的问题。 我使用自定义挂钩将内置 ._ 导入 _挂钩,该挂钩从字符串加载模块。

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'未定义”在行中“返回ILessons_1(请求);”。有趣的是python能够在这一行之上解决ajay。我很确定我在exec声明中犯了一些错误,但一直无法弄明白。

有些人可以帮我解决这个问题。 感谢

1 个答案:

答案 0 :(得分:0)

这里注意到几个问题:

1)globalslocals是内置函数名,不应将它们用作变量名。

2)可能是一个错误? (在ubuntu下用python 2.7.1测试)

请考虑以下代码(请注意 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()

这里注释的字符串(在 之后带有2个参数的exec)将不会像in the documentation中所描述的那样工作并导致:

NameError: global name 'foo' is not defined

但是可以手动组合全局变量+本地变量并将它们传递给exec(在我的示例中注释后的下一个字符串)。看起来像是一种解决方法。