gpt4 book ai didi

python-3.x - 内置打印 (stdout) 的异步版本

转载 作者:行者123 更新时间:2023-12-05 07:17:33 44 4
gpt4 key购买 nike

我无法理解在 async 函数中使用 print 的一些限制。基本上这是我的代码:

#!/usr/bin/env python
import sys
import asyncio
import aiohttp

async amain(loop):
session = aiohttp.ClientSession(loop=loop)

try:
# using session to fetch a large json file which is stored
# in obj

print(obj) # for debugging purposes

finally:
await session.close()


def main():
loop = asyncio.get_event_loop()

res = 1

try:
res = loop.run_until_complete(amain(loop, args))
except KeyboardInterrupt:
# silence traceback when pressing ctrl+c
pass

loop.close()

return res


if __name__ == '__main__':
sys.exit(main())

如果我执行这个,然后 json 对象被打印到 stdout 并且突然死于这个错误

$ dwd-get-sensor-file ; echo $?
Traceback (most recent call last):
File "/home/yanez/anaconda/py3/envs/mondas/bin/dwd-get-sensor-file", line 11, in <module>
load_entry_point('mondassatellite', 'console_scripts', 'dwd-get-sensor-file')()
File "/home/yanez/projects/mondassatellite/mondassatellite/mondassatellite/bin/dwd_get_sensor_file.py", line 75, in main
res = loop.run_until_complete(amain(loop, args))
File "/home/yanez/anaconda/py3/envs/mondas/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
return future.result()
File "/home/yanez/projects/mondassatellite/mondassatellite/mondassatellite/bin/dwd_get_sensor_file.py", line 57, in amain
print(obj)
BlockingIOError: [Errno 11] write could not complete without blocking
1

有趣的是,当我执行我的代码时,将 stdout 重定向到这样的文件

$ dwd-get-sensor-file > output.txt ; echo $?
0

异常没有发生,整个输出被正确重定向到 output.txt

出于测试目的,我将 json 对象转换为字符串,而不是执行 print(obj) 我执行 sys.stdout.write(obj_as_str) 然后我得到这个异常:

BlockingIOError: [Errno 11] write could not complete without blocking
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>

我已经搜索了这个 BlockingIOError 异常,但我发现的所有线程都与网络套接字或 CI 构建有关。但我找到了一个有趣github comment :

The make: write error is almost certainly EAGAIN from stdout. Pretty much every command line tool expects stdout to be in blocking mode, and does not properly retry when in nonblocking mode.

所以当我执行这个

python -c 'import os,sys,fcntl; flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL); print(flags&os.O_NONBLOCK);'

我得到 2048,这意味着阻塞(或者这是相反的方式?我很困惑)。执行后

python -c 'import os,sys,fcntl; flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL); fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags&~os.O_NONBLOCK);'

我不再收到 BlockingIOError 异常,但我不喜欢这个解决方案。

所以,我的问题是:在 async 函数中写入 stdout 时,我们应该如何处理?如果我知道我正在处理 stdout,我应该将 stdout 设置为非阻塞并在我的程序退出时将其还原?对此有具体的策略吗?

最佳答案

aiofiles尝试使用 stdout FD 作为文件对象。

aiofiles helps with this by introducing asynchronous versions of files that support delegating operations to a separate thread pool.

就直接将 aiofiles 与 FD 一起使用而言,您可能可以扩展 aiofiles.os module , 使用 wrap(os.write)

关于python-3.x - 内置打印 (stdout) 的异步版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58751221/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com