Importing a python module without actually executing it

后端 未结 6 2071
抹茶落季
抹茶落季 2020-12-10 01:48

In the context of a complex application, I need to import user-supplied \'scripts\'. Ideally, a script would have

def init():
    blah

def execute():
    mo         


        
6条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-10 02:33

    Here's a simpler (and more naive) alternative to the AST approach:

    import sys
    from imp import find_module, new_module, PY_SOURCE
    
    
    EXPECTED = ("init", "execute", "cleanup")
    
    def import_script(name):
        fileobj, path, description = find_module(name)
    
        if description[2] != PY_SOURCE:
            raise ImportError("no source file found")
    
        code = compile(fileobj.read(), path, "exec")
    
        expected = list(EXPECTED)
        for const in code.co_consts:
            if isinstance(const, type(code)) and const.co_name in expected:
                expected.remove(const.co_name)
        if expected:
            raise ImportError("missing expected function: {}".format(expected))
    
        module = new_module(name)
        exec(code, module.__dict__)
        sys.modules[name] = module
        return module
    

    Keep in mind, this is a very direct way of doing it and circumvents extensions to Python's import machinery.

提交回复
热议问题