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

发布于 2024-12-28 13:10:51 字数 1468 浏览 1 评论 0原文

我对 python 很陌生。这是我遇到的问题。 我已经将 builtin._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 

当我运行此代码时,我在“return ILessons_1(request);”行中收到错误“全局名称'ajay'未定义”。有趣的是,python 能够解析该行上方的 ajay。我很确定我在 exec 语句中犯了一些错误,但无法弄清楚。

有人可以帮我解决这个问题吗? 谢谢

I'm very new to python. Here is the problem Im having.
I have hooked the builtin._import_ with my custom hook which loads a module from a string.

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)

Then I use this hook in function which is loading a module and calling its function in exec statement.

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 

When I run this code I get error "global name 'ajay' is not defined"in line "return ILessons_1(request);". Interesting thing is python is able to resolve ajay in line just above this line. Im pretty sure Im making some mistake in exec statement but have not been able to figure out.

Can some please help me solve this problem.
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

川水往事 2025-01-04 13:10:51

这里注意到一些问题:

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()

此处注释字符串(在 in 之后带有 2 个参数的 exec)将无法按描述工作在 文档中 并导致:

NameError: global name 'foo' is not defined

但是人们可以手动将 globals+locals 与将它们传递给exec(在我的示例中注释后的下一个字符串)。对我来说似乎是一个解决方法。

Noted few issues here:

1) globals and locals are built-in function names, You should not use them as variable names.

2) Possibly a bug? (tested with python 2.7.1 under ubuntu)

Consider following code (note the exec statement):

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()

Here commented string (exec with 2 arguments after in) will not work as described at in the documentation and result in:

NameError: global name 'foo' is not defined

But one may manually combine globals+locals an pass them to exec (next string after comment in my example). Looks like a workaround to me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文