运行 通过子进程的 py 文件给出的输出与直接 运行 文件不同

Running a py file through subprocess gives different output than running the file directly

我正在尝试使用 subprocess 生成一堆测试用例,但出了点问题。 为什么以下(简化示例)不起作用?

我有第一个简单的程序sphere.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-
PI = 3.141592
radius = float(input( 'Give the radius of the sphere (in cm): ' ))

area = 4*PI*pow(radius, 2)
volume = 4/3*PI*pow(radius, 3)

print("\narea: {} cm²\nvolume: {} cm³".format(round(area,2),round(volume,2)))

其中 4 的输入导致(在 运行 python3 sphere.py 之后):

area: 201.06 cm²
volume: 268.08 cm³

然后我有另一个文件,generator.py,它运行第一个 subprocess:

import subprocess

res = subprocess.run(["python", "sphere.py"], input="4",
                     capture_output=True, encoding="utf")

result_lines = res.stdout.split("\n")
for line in result_lines:
    print(line)

但这会导致(不同的音量,在 运行 python3 generator.py 之后):

Give the radius of the sphere (in cm): 
area: 201.06 cm²
volume: 201.06 cm³

奇怪的是,当我将 volume 公式更改为 4.0/3.0*PI*pow(radius, 3) 时,它似乎工作正常...

这是怎么回事?

使用 Python 3.8

在同时安装了 Python 2 和 3 的系统上通常发生的情况是,python 命令链接到 Python 2,而 python3 链接到...很明显 Python 3.

因此,当您 运行 使用 Python 3 从 shell 连接文件时, 子进程调用会调用 Python 2 口译员。所以简单的解决方法是强制它使用 Python 3:

subprocess.run(["python3", "sphere.py"], ...)

或使用 sys.executable 以确保使用相同的 Python 解释器:

import sys

subprocess.run([sys.executable, "sphere.py"], ...)

或者,从另一个文件中找到 better way 到 运行 的 Python 文件。


这个问题的提示是the difference with the division operator between Python 2 and 3。在 python 2 中,4/3 将给出 1。而在 Python 3 中,它将给出 1.333。当您执行 4.0/3.0 时,它会强制 Python 2 解释器也使用浮点除法,因此问题得到解决。

有趣的是,使用 4 作为输入使两个公式等价(在 Python 2 下)。 4/3 变成 1 不影响,radius 的乘方等于乘以 4,所以结果类似。