【问题标题】:How to convert output from subprocess to list of dictionaries如何将子进程的输出转换为字典列表
【发布时间】:2021-10-25 14:29:56
【问题描述】:

我的任务之一是调用 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 json python-3.x subprocess script


    【解决方案1】:

    绝对最好的解决方案是不要将 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 与子进程之间。

    【讨论】:

    • 感谢您的回答。我正在使用 python3.6 并使用您的代码,我遇到了 2 个错误第一个 - TypeError: __init__() got an unexpected keyword argument 'capture_output'....2nd - TypeError: __init__() got an unexpected keyword argument 'text'
    • 关键字参数capture_outputtext 比这要新一些。如果您真的停留在 3.6 上,您将不得不恢复使用显式 stdout=subprocess.PIPE 等并切换到旧同义词 universal_newlines=True 而不是 text=True ...仍然 run 应该是一个不完整的显着改进通过Popen 临时重新实现。您会注意到 3.6 计划于 2021 年底 EOL。
    • 当然,我的主要建议仍然是不要将 Python 作为其自身的子进程运行。
    猜你喜欢
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多