python -m的sys.argv行为

时间:2017-02-06 20:28:54

标签: python python-3.x python-import

关于python 3.5.2中__init__.py行为的问题。我注意到“sys.argv”和“import __main__”的行为取决于它们被调用的时间。例如:

$ tree 
└── subdir
    ├── __init__.py : "import sys; print(sys.argv)"
    ├── __main__.py : "import sys; print(sys.argv)"

$ python -m subdir
['-m']
['/path/to/code/subdir/__main__.py']

这里我措手不及,因为我希望sys.argv在整个流程生命周期中都是一样的。我有直觉为什么会发生这种情况,但我想知道是否有任何方法可以在导入时知道__init__.py模块中真正的sys.argv是什么。

作为参考,看起来在lib /runpy.py@_run_module_as_main

中更改了argv

1 个答案:

答案 0 :(得分:2)

简短版本:在运行之前无法找到__main__

长版:

  • -m标志导致sys.argv [0]被操纵
  • 问题在于操作sys.argv的时间
    • main.c@Py_main执行一些标记解析并弹出模块名称以调用
    • main.c@RunModule runpy.py@_run_module_as_main
    • 的包装器
    • _run_module_as_main设置sys.argv [0]但在调用runpy.py@_get_main_module_details之前不会这样做
      • _get_module_details中的副作用实际上导入了包及其祖先,它们在_get_main_module_details可以解析之前执行__init__.py脚本,因此_run_module_as_main无法设置sys.argv

我认为这可以重构,以便在_get_module_details导入包和祖先之前设置sys.argv(我认为可以通过module specs生成)但是必须等待对runpy体系结构的增强,可能在截至去年年底正在进行的this形式。