为什么我的Python async / await实际上不会写matplotlib文件?

问题描述 投票:2回答:2

我的代码是:

import os
import h5py
import asyncio
import numpy as np
import matplotlib.pyplot as plt
from dotenv import load_dotenv
load_dotenv()

data_path = os.environ['DATA_PATH']
output_data_path = os.environ['OUTPUT_DATA_PATH']
patient_files = os.listdir(data_path)


async def save_file(filename, image_data):
    plt.imshow(image_data, cmap='gray')
    await plt.savefig(filename, pad_inches=0, bbox_inches='tight')

for patient_file in patient_files:
    patient_parts = patient_file.split('.')
    patient_parts = patient_parts[0].split('_')
    patient_id = patient_parts[1]
    if int(patient_id) < 21:
        continue
    print('Doing patient', patient_id)

    patient_data = h5py.File(os.path.join(data_path, patient_file))
    variables = patient_data.items()

    for var in variables:
        name = var[0]
        data = var[1]

        if type(data) is h5py.Dataset:
            value = data.value
            plt.axis('off')
            if name == 'Svar25':
                for layer in range(value.shape[0]):
                    output_file = os.path.join(
                        output_data_path, patient_id + '_FLAIR_debone_' + str(layer) + '.png')
                    save_file(filename=output_file, image_data=value[layer])

            if name == 'Svar24':
                for layer in range(value.shape[0]):
                    output_file = os.path.join(
                        output_data_path, patient_id + '_FLAIR_bone_' + str(layer) + '.png')
                    save_file(filename=output_file, image_data=value[layer])

我试图异步编写我的文件,但实际上并没有写。

我究竟做错了什么?

python matplotlib python-asyncio
2个回答
3
投票

我究竟做错了什么?

await plt.savefig(filename, pad_inches=0, bbox_inches='tight')

函数不会因为你之前使用await而变得异步。你必须declare函数作为async def使其首先异步。

任何使用await的函数都应定义为async def,直到程序的入口点(如async def main())。你应该run entry point in event loop使异步代码工作。

plt.imshowplt.savefig这两个函数都是同步的。您可以尝试使用run_in_executor将第二个转换为异步并等待结果,但我不确定它是否可行。我也不确定你是否需要它:你可能无法实现与这些磁盘I / O操作并行的任何加速。


长话短说,请阅读this answer以更好地理解为什么人们首先使用asyncio。我还建议你阅读this part of documentation并从更琐碎的异步任务开始。


2
投票

你忘了在await之前添加save_file(...)。这意味着asyncio循环永远不会调度文件写入功能。

在我的经历中非常常见的错误......

更新:从您的评论中,您似乎永远不会启动asyncio循环来处理函数。根据docs,您需要启动顶级功能。 Python 3.7有一个很好的新的简单语法,原理在3.5和3.6中相同但有点啰嗦。

>>> import asyncio

>>> async def main():
...     print('hello')
...     await asyncio.sleep(1)
...     print('world')

>>> asyncio.run(main())
hello
world
© www.soinside.com 2019 - 2024. All rights reserved.