如何将子流程的输出转换为字典列表

How to convert output from subprocess to list of dictionaries

我的任务之一是调用 python 脚本并从脚本中获取输出并对其执行一些操作。我写了下面的代码。

import subprocess
import json
chief_complaint = """ "Eernise, Randell is an 64-year-old male" """
command= """python predict_icd.py --cc """+str(chief_complaint)
command_proc=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
print("response - ",command_proc.stdout.read())

我从上面的代码得到的输出是

command_proc.stdout.read() -  b"[{'text': 'CHA', 'start': 51, 'end': 54, 'code': ''}, {'text': 'CHA', 'start': 221, 'end': 224, 'code': ''}, {'text': 'dog', 'start': 286, 'end': 289, 'code': ''}, {'text': 'Schizophrenia', 'start': 351, 'end': 364, 'code': 'F20'}, {'text': 'chronic pain', 'start': 366, 'end': 378, 'code': 'G89.29'}, {'text': 'chest pain', 'start': 599, 'end': 609, 'code': 'R07.89'}, {'text': 'palpitations', 'start': 613, 'end': 625, 'code': 'R00.2'}, {'text': 'cough', 'start': 829, 'end': 834, 'code': 'R05'}, {'text': 'wheezing', 'start': 836, 'end': 844, 'code': 'R06.2'}, {'text': 'pain', 'start': 966, 'end': 970, 'code': ''}, {'text': 'schizophrenia', 'start': 1078, 'end': 1091, 'code': 'F20'}]\n"

我想将此输出转换为字典列表以执行某些操作。 如果有任何替代方法来调用脚本并获取输出,请提出更好的方法。

绝对最好的解决方案是不要 运行 Python 作为其自身的子进程。相反,重构 predict_icd.py 以便您可以 import 它并直接调用它的函数。参见 What is the best way to call a script from another script?

您的第二个最佳选择是更改 predict_icd.py,以便它以 JSON 等标准格式打印结果。然后你可以从任何工具调用它,而不仅仅是 Python.

遥远的第三个选择是使用你所拥有的并使用 ast.literal_eval() 来解析结果。我还重构为 avoid the pesky and unnecessary shell=True 并修复了孤立的 Popen.

import subprocess
# import json  # unused import
from ast import literal_eval

chief_complaint = """ "Eernise, Randell is an 64-year-old male" """
command_proc = subprocess.run(
    ['python', 'predict_icd.py', '--cc', chief_complaint],
    capture_output=True, text=True, check=True)
response = literal_eval(command_proc.stdout)
print("response = ", response)

更详细地说,Popen只会启动一个进程;如果你这样做,你必须在它的生命周期内照顾它 - 但 subprocess.run() 已经为你处理了所有这些管道。正如它的文档所说,当标准库中的高级函数已经做你想做的事情时,避免 Popen

另请注意 text=True,它告诉 Python 发送和接收文本,而不是 bytes 到子进程和从子进程接收文本。