Python,将代码注入模块全局变量

Net*_*ave 3 python dictionary module python-3.x

我试图绕过从模块导入,所以在我__init__.py可以注入这样的代码:

globals().update(
    {
         "foo": lambda: print("Hello stackoverflow!")
    }
)
Run Code Online (Sandbox Code Playgroud)

所以,如果我这样做,import mymodule我就能打电话mymodule.foo.这是一个简单的概念,对于此目的无用,因为您实际上只能定义foo.所以,想法是修改globals模块字典,所以万一它找不到函数foo它会去任何地方我可以注入代码,为此我试过:

from importer import load #a load function to search for the code
from functools import wraps

def global_get_wrapper(f):
    @wraps(f)
    def wrapper(*args):
        module_name, default = args
        res = f(*args)
        if res is None:
            return load(module_name)
        return res
    return wrapper

globals().get = global_get_wrapper(globals().get) # trying to substitute get method
Run Code Online (Sandbox Code Playgroud)

但它给了我一个错误:

AttributeError: 'dict' object attribute 'get' is read-only
Run Code Online (Sandbox Code Playgroud)

我的另一个想法是将可用的函数,类等名称预加载到模块字典中,然后懒洋洋地加载它们.

我没有想法来完成这个,我不知道这是否可能.我应该去写我自己的python导入器吗?还是有其他我无法思考的可能性?提前致谢.

Vad*_*der 9

而不是黑客攻击globals()最好__getattr__为您的模块定义如下:

module_name.py

foo = 'foo'

def bar():
    return 'bar'
Run Code Online (Sandbox Code Playgroud)

my_module.py

import sys

import module_name

class MyModule(object):
    def foobar(self):
        return 'foobar'

    def __getattr__(self, item):
        return getattr(module_name, item)

sys.modules[__name__] = MyModule()
Run Code Online (Sandbox Code Playgroud)

然后:

>>> import my_module
>>> my_module.foo
'foo'
>>> my_module.bar()
'bar'
>>> my_module.foobar()
'foobar'
Run Code Online (Sandbox Code Playgroud)