【问题标题】:Python 3 weird behavior of subprocess.callsubprocess.call 的 Python 3 奇怪行为
【发布时间】:2020-03-09 20:01:31
【问题描述】:

环境:

Windows: 10
Python: 2.7.13 and 3.8.1
default Python launcher: py -3
Default python: 2.7.13

> python -V
> Python 2.7.13

> py -3 -V
> Python 3.8.1



启动器.py:

import subprocess
subprocess.call(['python', '-V'])


  1. 测试 1:py -3 launcher.py

    输出:python 3.8.1(如何!)

  2. 测试 2:py -2 launcher.py

    输出:Python 2.7.13


输出应该只是Python 2.7.13,即使启动器在py 3下运行!
请注意,添加shell=True 会起作用,但我的想法是不要使用它,如果我跑了

subprocess.call(['python', 'script_under_py_2.py']) # Will run python 3 with script python 2!

谢谢
亚当

【问题讨论】:

  • 有趣!当我在 macOS 上执行此操作时,我得到了正确的结果:python2 和 python3 都显示相同的 python -V
  • 更改 launcher.py 以使用 sys.executable 而不是 'python'。前者是当前运行的 Python 解释器的路径。
  • @martineau 这与 OP 想要的相反。由于我无法想象的原因,他似乎想要一个可以在 python 2 或 python 3 下运行但最终会启动 python 2 子进程的启动器。所以,如果用py -3启动,他实际上是想保证目标是not sys.executable

标签: python python-3.x subprocess


【解决方案1】:

此行为是由于在 Windows 和 Unix 上调用 Popen 时对 PATH 环境变量的处理不一致造成的。

Windows 使用CreateProcess 函数创建其子进程。 CreateProcess includes 父进程目录的搜索路径,这可能是您执行不同二进制文件的原因。

在 Windows 上,仅当 shell=True 也被传递时才考虑 PATH。

您可以在此处了解有关此问题的更多信息:

【讨论】:

  • 感谢您的回复,您添加的参考资料很好,似乎还没有一个干净的解决方案:S.
【解决方案2】:

如果问题是subprocess.call 未能兑现os.environ['PATH'],那么您始终可以在该路径中显式搜索您要调用的可执行文件,然后通过其绝对路径调用它,如下所示:

# Manually search the operating system's PATH for python[.exe]
import os, sys
ospath = os.environ['PATH'].split(os.path.pathsep)
_, extension = os.path.splitext(sys.executable)
target = 'python' + extension
matches = [os.path.join(directory, target) for directory in ospath]
matches = [match for match in matches if os.path.isfile(match)]
if not matches: raise OSError('{!r} was not found in any PATH directory'.format(target))
python = matches[0]

# Test:
import subprocess
print('I am Python {} and I am calling "{}" -V'.format(sys.version.split()[0], python))
subprocess.call([python, '-V'])

当然,如果 py -3 包装器通过在启动 Python 之前实际更改路径来工作,那 不会 做你想做的事......我不熟悉那个包装器,所以我不不知道会不会有问题。

【讨论】:

  • 感谢您的回复,我希望可以这样做,如果是一个脚本或已知输入,这是一个很好的解决方案,问题出在用户输入中,可以是“python ...”,似乎需要做额外的脏逻辑!
猜你喜欢
  • 2020-08-27
  • 2020-07-06
  • 1970-01-01
  • 2022-08-23
  • 2021-04-29
  • 1970-01-01
  • 2020-10-22
  • 2013-04-01
  • 1970-01-01
相关资源
最近更新 更多