Python异步IO任务列表进度日志记录

Python异步IO任务列表进度日志记录,python,python-3.x,python-asyncio,Python,Python 3.x,Python Asyncio,我需要处理大量的数据行,只有异步处理才有意义 我需要查看列表处理状态,即完成处理1/3,但当我增加计数器时,它始终保持在1。这是有意义的,因为我将计数器发送到函数中。我需要这样做,因为如果没有它,我会: UnboundLocalError: local variable 'processed' referenced before assignment 使用Python 3.8 任何帮助都将不胜感激 以下是测试的链接: 我将代码抽象如下: import os, logging i

我需要处理大量的数据行,只有异步处理才有意义

我需要查看列表处理状态,即
完成处理1/3
,但当我增加计数器时,它始终保持在1。这是有意义的,因为我将计数器发送到函数中。我需要这样做,因为如果没有它,我会:

UnboundLocalError: local variable 'processed' referenced before assignment
使用Python 3.8

任何帮助都将不胜感激

以下是测试的链接:

我将代码抽象如下:

    import os, logging
    import asyncio
     
    logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s', datefmt='%d-%b-%y %H:%M:%S')
    logger = logging.getLogger(__name__)
     
    items = [{"name": "A"}, {"name": "B"}, {"name": "C"}]
     
    processed = 0
     
    async def increment(item):
        count = item.get('count', 0)
        count += 1
        return count
     
    async def get_and_update(item, processed):
        item['count'] = await increment(item)
        # Show progress now, but how?
        processed += 1
        logger.info(f"You can't see me {processed}")
     
    async def run():
        logger.info(f"Processing {len(items)} items...")
        await asyncio.gather(*[
            asyncio.create_task(
                get_and_update(item, processed)
            ) for item in items
        ])
     
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
我得到的结果是:

28-Aug-20 11:19:22 INFO     [prog.py:23] Processing 3 items...
28-Aug-20 11:19:22 INFO     [prog.py:20] You can't see me 1
28-Aug-20 11:19:22 INFO     [prog.py:20] You can't see me 1
28-Aug-20 11:19:22 INFO     [prog.py:20] You can't see me 1

您的基本问题是,通过将
processed
声明为
get\u and\u update
的参数,您正在隐藏全局
processed
变量。您需要删除参数,然后在该函数中将
processed
声明为全局,如下所示:

import os, logging
import asyncio
 
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s', datefmt='%d-%b-%y %H:%M:%S')
logger = logging.getLogger(__name__)
 
items = [{"name": "A"}, {"name": "B"}, {"name": "C"}]
 
processed = 0
 
async def increment(item):
    count = item.get('count', 0)
    count += 1
    return count
 
async def get_and_update(item):
    global processed

    item['count'] = await increment(item)
    # Show progress now, but how?
    processed += 1
    logger.info(f"You can't see me {processed}")
 
async def run():
    logger.info(f"Processing {len(items)} items...")
    await asyncio.gather(*[
        asyncio.create_task(
            get_and_update(item)
        ) for item in items
    ])
 
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
上面的输出是:

28-Aug-20 08:15:00 INFO     [asynctest.py:25] Processing 3 items...
28-Aug-20 08:15:00 INFO     [asynctest.py:22] You can't see me 1
28-Aug-20 08:15:00 INFO     [asynctest.py:22] You can't see me 2
28-Aug-20 08:15:00 INFO     [asynctest.py:22] You can't see me 3

您的基本问题是,通过将
processed
声明为
get\u and\u update
的参数,您正在隐藏全局
processed
变量。您需要删除参数,然后在该函数中将
processed
声明为全局,如下所示:

import os, logging
import asyncio
 
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s', datefmt='%d-%b-%y %H:%M:%S')
logger = logging.getLogger(__name__)
 
items = [{"name": "A"}, {"name": "B"}, {"name": "C"}]
 
processed = 0
 
async def increment(item):
    count = item.get('count', 0)
    count += 1
    return count
 
async def get_and_update(item):
    global processed

    item['count'] = await increment(item)
    # Show progress now, but how?
    processed += 1
    logger.info(f"You can't see me {processed}")
 
async def run():
    logger.info(f"Processing {len(items)} items...")
    await asyncio.gather(*[
        asyncio.create_task(
            get_and_update(item)
        ) for item in items
    ])
 
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
上面的输出是:

28-Aug-20 08:15:00 INFO     [asynctest.py:25] Processing 3 items...
28-Aug-20 08:15:00 INFO     [asynctest.py:22] You can't see me 1
28-Aug-20 08:15:00 INFO     [asynctest.py:22] You can't see me 2
28-Aug-20 08:15:00 INFO     [asynctest.py:22] You can't see me 3

您发现日志记录有什么挑战性?@larsks我添加了一个链接,显示我的问题。请在问题中包括您询问的代码以及任何错误。我已简要查看了您的链接,没有发现任何与日志记录相关的错误,但我确实看到了您在本问题中未提及的错误。
asyncio
(及类似)的优点是适用于高延迟、I/O绑定的任务。这个用例没有这些。考虑使用<代码>多重处理< /代码>。你能解释你的问题是什么吗?你的预期产出是多少?您是否知道,
处理的
是本地的
获取和更新
,因此总是
0+1
,即
1
?您发现日志记录有什么挑战性?@larsks我添加了一个链接,显示了我的问题请在问题中包括您询问的代码以及任何错误。我已简要查看了您的链接,没有发现任何与日志记录相关的错误,但我确实看到了您在本问题中未提及的错误。
asyncio
(及类似)的优点是适用于高延迟、I/O绑定的任务。这个用例没有这些。考虑使用<代码>多重处理< /代码>。你能解释你的问题是什么吗?你的预期产出是多少?您是否知道
processed
get_和_update
本地的,因此总是
0+1
,即
1