检索 Python 解释器的命令行参数
Retrieve the command line arguments of the Python interpreter
受到的启发,我想以一种可移植的方式检索Python解释器的完整命令行。也就是说,我想获得解释器的原始 argv
,而不是排除解释器本身选项的 sys.argv
(如 -m
、-O
等)。
sys.flags
告诉我们设置了哪些布尔选项,但它没有告诉我们有关 -m
参数的信息,并且标志集必然会随着时间而改变,从而造成维护负担。
在 Linux 上,您可以使用 procfs 检索原始命令行,但这不可移植(而且有点恶心):
open('/proc/{}/cmdline'.format(os.getpid())).read().split('[=11=]')
你可以使用 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'
我要为此添加另一个答案。 @bav 对 Python 2.7 有正确的答案,但它在 Python 3 中中断,正如 @szmoore 指出的(不仅仅是 3.7)。但是,下面的代码将在 Python 2 和 Python 3 中工作(关键是 Python 3 中的 c_wchar_p
而不是 c_char_p
Python 2) 并将正确地将 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
您会注意到它还 returns 仅 解释器参数并排除了 sys.argv
中的扩充。您可以通过删除 - len(sys.argv) + 1
.
来消除此行为
受到argv
,而不是排除解释器本身选项的 sys.argv
(如 -m
、-O
等)。
sys.flags
告诉我们设置了哪些布尔选项,但它没有告诉我们有关 -m
参数的信息,并且标志集必然会随着时间而改变,从而造成维护负担。
在 Linux 上,您可以使用 procfs 检索原始命令行,但这不可移植(而且有点恶心):
open('/proc/{}/cmdline'.format(os.getpid())).read().split('[=11=]')
你可以使用 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'
我要为此添加另一个答案。 @bav 对 Python 2.7 有正确的答案,但它在 Python 3 中中断,正如 @szmoore 指出的(不仅仅是 3.7)。但是,下面的代码将在 Python 2 和 Python 3 中工作(关键是 Python 3 中的 c_wchar_p
而不是 c_char_p
Python 2) 并将正确地将 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
您会注意到它还 returns 仅 解释器参数并排除了 sys.argv
中的扩充。您可以通过删除 - len(sys.argv) + 1
.