检索 Python 解释器的命令行参数

Posted

技术标签:

【中文标题】检索 Python 解释器的命令行参数【英文标题】:Retrieve the command line arguments of the Python interpreter 【发布时间】:2015-04-04 20:43:26 【问题描述】:

受another question here 的启发,我想以可移植的方式检索 Python 解释器的完整命令行。也就是说,我想获取解释器的原始argv,而不是排除解释器本身选项的sys.argv(如-m-O 等)。

sys.flags 告诉我们设置了哪些布尔选项,但它没有告诉我们有关 -m 参数的信息,并且标志集必然会随着时间而改变,从而造成维护负担。

在 Linux 上,您可以使用 procfs 检索原始命令行,但这不是可移植的(而且有点粗糙):

open('/proc//cmdline'.format(os.getpid())).read().split('\0')

【问题讨论】:

这是一个很好的问题......据我所知,这是不可能的(在 CPython 中)。在我看来,Py_Main 进行了一些解析以获取命令行参数,然后使用剩余的参数调用 PySys_SetArgv,而对 *argc**argv 不执行任何其他操作。有Py_GetArgcArgv,您可能会使用它——但我在文档化的 C-API 中的任何地方都看不到它... .split('\0') 会比 .replace('\0', ' ') 更正确——否则您无法区分包含空格的参数和单独的参数。 【参考方案1】:

你可以使用 ctypes

~$ python2 -B -R -u
Python 2.7.9 (default, Dec 11 2014, 04:42:00) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Persistent session history and tab completion are enabled.
>>> import ctypes
>>> argv = ctypes.POINTER(ctypes.c_char_p)()
>>> argc = ctypes.c_int()
>>> ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(argc), ctypes.byref(argv))
1227013240
>>> argc.value
4
>>> argv[0]
'python2'
>>> argv[1]
'-B'
>>> argv[2]
'-R'
>>> argv[3]
'-u'

【讨论】:

这不再适用于 Python 3.7 >>> argv[0] 现在是 b'p'【参考方案2】:

我将为此添加另一个答案。 @bav 对 Python 2.7 有正确的答案,但正如 @szmoore 指出的那样(不仅仅是 3.7),它在 Python 3 中出现了问题。然而,下面的代码将在 Python 2 和 Python 3 中工作(关键是 Python 3 中的 c_wchar_p 而不是 Python 2 中的 c_char_p),并且将正确地将 argv 转换为 Python 列表,以便在没有段错误的情况下在其他 Python 代码中使用是安全的:

def get_python_interpreter_arguments():
    argc = ctypes.c_int()
    argv = ctypes.POINTER(ctypes.c_wchar_p if sys.version_info >= (3, ) else ctypes.c_char_p)()
    ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(argc), ctypes.byref(argv))

    # Ctypes are weird. They can't be used in list comprehensions, you can't use `in` with them, and you can't
    # use a for-each loop on them. We have to do an old-school for-i loop.
    arguments = list()
    for i in range(argc.value - len(sys.argv) + 1):
        arguments.append(argv[i])

    return arguments

您会注意到它还返回解释器参数,并排除在sys.argv 中找到的增强。您可以通过删除 - len(sys.argv) + 1 来消除此行为。

【讨论】:

您使用的是什么操作系统平台和解释器版本?在这两个测试中,我都试过它崩溃了。我在 Windows 10 上使用 Python 3.7 进行了测试,在 Debian 9 上使用 Python 3.5 进行了测试。 以上在 Ubuntu 16.04 和 macOS 10.13 上的 Python 2.7、3.5、3.6 和 3.7 上运行。我不使用 Windows,所以我无法对此进行测试。我基本上假设 Python 中所有与 C 相关的东西在 Windows 中的工作方式完全不同(或者只是不工作)。但这绝对适用于看似广泛的 Unix。 @JamesThomasMoon 在 Ubuntu 20.04 和 Python 3.8.10 和 2.7.18 上为我工作。

以上是关于检索 Python 解释器的命令行参数的主要内容,如果未能解决你的问题,请参考以下文章

Python3之命令行参数处理

python 命令行下的命令参数

Python 安装与命令行参数 ,Pip 的命令参数--官方文档

Python 的几个命令行参数

python开发简单的命令行工具

python命令行传入参数方式