[英]Is there a way to check if script is running from subprocess?
假设我有一个 python 脚本,它读取文件夹中的所有图像并调整它们的大小。 该脚本完全由他自己运行,它接受两个参数 - 输入文件夹和输出文件夹。 为了获得进度的视觉响应,我使用了一个打印到控制台/终端的进度条。
调整大小.py:
import argparse
import fnmatch
import os
import PIL
from PIL import Image
from progress.bar import Bar
parser = argparse.ArgumentParser(description='Photo resizer.')
parser.add_argument('input_folder', nargs='?', default='', help="Input folder")
parser.add_argument('export_folder', nargs='?', default='', help="Output folder")
args = parser.parse_args()
if args.input_folder:
input_folder = args.input_folder
if args.export_folder:
export_resized_folder = args.export_folder
NEW_SIZE = 2000
inputFiles = []
for root, dirnames, filenames in os.walk(input_folder):
for filename in fnmatch.filter(filenames, '*.jpg'):
inputFiles.append(os.path.join(root, filename))
bar = Bar("Processing photos", max=len(inputFiles), check_tty=False)
for photo in inputFiles:
filename = os.path.basename(photo)
im = Image.open(photo)
im_width, im_height = im.size
if im_width > im_height:
new_width = NEW_SIZE
new_height = int(NEW_SIZE * im_height / im_width)
else:
new_height = NEW_SIZE
new_width = int(NEW_SIZE * im_width / im_height)
new_size = (new_width, new_height)
im_resized = im.resize(new_size, resample=PIL.Image.Resampling.LANCZOS)
im_resized.save(os.path.join(export_resized_folder, filename), quality=70)
bar.next()
bar.finish()
现在我有另一个脚本(main_gui.py),它进行一些批处理,其中一项工作是调整图像大小。 该脚本提供了一个简单的 GUI。 在调整图像大小时,我使用subprocess Popen
执行脚本并将输入和输出文件夹作为 args 传递。
所以在main_gui.py我启动子进程:
script_path = "resize.py"
process = subprocess.Popen(["python", script_path, INPUT_FOLDER, OUTPUT_FOLDER], universal_newlines=True, stdout=subprocess.PIPE)
现在我也想看看 GUI 的进展。 我不知道我是否做对了(很有可能不是,这只是我想到的第一件事)......
因此,在resize.py和进度条中,我打印出有关我的进度的信息,然后在main_gui.py中读取它,并根据该信息更新 tkinter 进度条。
在resize.py中:
bar = Bar("Processing photos", max=len(inputFiles), check_tty=False)
print("**TOTAL** " + str(len(inputFiles)))
...
progressCounter = 1
for photo in inputFiles:
...
bar.next()
print("**PROGRESS** " + str(progressCounter))
progressCounter += 1
...
我在main_gui.py中阅读了这些值
process = subprocess.Popen(["python", script_path], universal_newlines=True, stdout=subprocess.PIPE)
while process.poll() is None:
data = process.stdout.readline().strip()
print(data)
if "**TOTAL** " in data:
total = int(data.replace("**TOTAL** ", ""))
progressbarWidget['maximum'] = total
if "**PROGRESS** " in data and self.GUI:
progressCounter = int(data.replace("**PROGRESS** ", ""))
progressbarWidget['value'] = progressCounter
progressbarWidget.update_idletasks()
在这一点上,我想在我的resize.py中检查它是由自己运行还是由子进程运行,所以我没有不必要的打印语句。
正如查尔斯在评论中建议的那样,我尝试传入一个 env 值,但无法完成
对于这个用例来说,试图检测你的父进程是不必要的魔法。 使用可选参数使其显式化将使其他人编写自己的 GUI(可能使用非 Python 语言)获得机器可读的状态输出,而无需尝试欺骗检测。
parser = argparse.ArgumentParser(description='Photo resizer.')
parser.add_argument('--progress', choices=('none', 'human', 'machine-readable'), default='none',
help="Should a progress bar be written to stderr in a human-readable form, to stdout in a machine-readable form, or not at all?")
parser.add_argument('input_folder', nargs='?', default='', help="Input folder")
parser.add_argument('export_folder', nargs='?', default='', help="Output folder")
args = parser.parse_args()
……然后后来……
if args.progress == 'machine-readable':
pass # TODO: Write your progress messages for the programmatic consumer to stdout here
elif args.progress == 'human':
pass # TODO: Write your progress bar for a human reader to stderr here
在 GUI 端,将--progress=human
添加到参数列表中:
process = subprocess.Popen([sys.executable, script_path, '--progress=human'],
universal_newlines=True, stdout=subprocess.PIPE)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.