📜  runpy.py",第 194 行,在 _run_module_as_main 返回 _run_code(code, main_globals, None, - Python (1)

📅  最后修改于: 2023-12-03 14:47:10.121000             🧑  作者: Mango

介绍

在 Python 中,可以使用 runpy 模块中的 run_module_as_main 函数来直接运行一个模块文件作为主程序。在执行过程中,_run_module_as_main 函数返回了一个 _run_code 函数的调用结果。该函数用于运行 Python 代码。

代码片段
def _run_module_as_main(mod_name, alter_argv=None):
    """Helper to run module as if it's __main__"""
    if alter_argv is not None:
        sys.argv = alter_argv
    else:
        sys.argv = _sys.argv[:1] + ['-m', mod_name] + _sys.argv[1:]
    mod_name = re.sub(r'(-[__\d]+)+$', '', mod_name)
    code = _get_code_from_module(mod_name)
    # Copy sys.path and clean up globals namespace before running
    save_path = sys.path[:]
    globs = {
        '__name__': '__main__',
        '__file__': mod_name if mod_name != '__main__' else sys.argv[0],
        '__cached__': None,
        '__doc__': None,
        '__loader__': None,
        '__package__': None,
        '__spec__': None,
        '__annotations__': {},
    }
    try:
        run_name = "runpy.run_module.__run_module_as_main"
        sys.path.insert(0, os.path.dirname(code.co_filename))
        return _run_code(code, globs, None,  # Emulate __main__ namespace
                         "__main__", mod_name,                             # Emulate main module's name
                         alter_argv is not None, run_name)
    finally:
        sys.path[:] = save_path
        for key in {k for k in list(globs.keys()) if not k.startswith('__')}:
            del globs[key]
解释

首先,该函数会重置 sys.argv,设置为当前 Python 进程的参数加上 -m 和模块名,以模拟直接运行该模块的效果。

接着,将模块文件转化为 Python 代码,并复制一份 sys.pathsave_path 变量中备份。然后将 globs 变量设为一个空字典,并设置其中的几个变量,用于模拟 __main__ namespace,即主程序命名空间。

在运行 _run_code 函数时,传入 codeglobs 参数,使其在 __main__ 命名空间中执行代码。最后,将 sys.path 恢复为原来的值,并删除 globs 中除 __name__ 以外的变量。

代码片段摘自 Python runpy 模块中 _run_module_as_main 函数的源码。