简体   繁体   English

有没有办法检查脚本是否从子进程运行?

[英]Is there a way to check if script is running from subprocess?

Let's say I have a python script which reads all the images in a folder and resizes them.假设我有一个 python 脚本,它读取文件夹中的所有图像并调整它们的大小。 The script works all by his own, it takes in two arguments - the input folder and an output folder.该脚本完全由他自己运行,它接受两个参数 - 输入文件夹和输出文件夹。 To have a visual response of the progress I'm using a progressbar which is printed out to the console/terminal.为了获得进度的视觉响应,我使用了一个打印到控制台/终端的进度条。

resize.py:调整大小.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()

Now I have an another script (main_gui.py) which does some batch processing and one of the jobs is to resize the images.现在我有另一个脚本(main_gui.py),它进行一些批处理,其中一项工作是调整图像大小。 This script provides a simple GUI.该脚本提供了一个简单的 GUI。 When it comes to resizing the images, I use subprocess Popen to execute the script and pass in the input and output folders as args.在调整图像大小时,我使用subprocess Popen执行脚本并将输入和输出文件夹作为 args 传递。

So in main_gui.py I start the subprocess:所以在main_gui.py我启动子进程:

script_path = "resize.py"
process = subprocess.Popen(["python", script_path, INPUT_FOLDER, OUTPUT_FOLDER], universal_newlines=True, stdout=subprocess.PIPE)

Now I'd like to see the progress in the GUI also.现在我也想看看 GUI 的进展。 I don't know if I'm doing it correctly (It is a high probability that not, this is just the first thing that came to my mind)...我不知道我是否做对了(很有可能不是,这只是我想到的第一件事)......
So in resize.py along with the progressbar I print out information about my progress and then read it in the main_gui.py and based on that information I update a tkinter progressbar.因此,在resize.py和进度条中,我打印出有关我的进度的信息,然后在main_gui.py中读取它,并根据该信息更新 tkinter 进度条。

In resize.py :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
   ...

I read these values in main_gui.py我在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()

And at this point I'd like in my resize.py check if it is run by itself or by the subprocess, so I don't have the unnecessary print statements.在这一点上,我想在我的resize.py中检查它是由自己运行还是由子进程运行,所以我没有不必要的打印语句。

I tried pass in an env value as Charles suggested in the comments, but couldn't get it done正如查尔斯在评论中建议的那样,我尝试传入一个 env 值,但无法完成

Trying to detect your parent process is an unnecessary amount of magic for this use case.对于这个用例来说,试图检测你的父进程是不必要的魔法。 Making it explicit with an optional argument will let others writing their own GUIs (potentially in non-Python languages) get the machine-readable status output without needing to try to fool the detection.使用可选参数使其显式化将使其他人编写自己的 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()

...and then later... ……然后后来……

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

while on the GUI side, adding --progress=human to the argument list:在 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM