sys.argv python -m 的行为

sys.argv behavior with python -m

关于 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 是什么。

作为参考,argv 似乎在 Lib/runpy.py@_run_module_as_main

中发生了变化

短版:没办法找到__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

我认为这可以重构,使得 sys.argv 在 _get_module_details 导入包和祖先之前设置(我认为通过 module specs) but will have to wait for an enhancement to the runpy architecture, possibly in the form of this 成为可能,最近正在进行中去年