簡體   English   中英

如何在指定* args或** kwargs的同時從函數字典運行函數

[英]How to run functions from a dict of functions while specifying *args or **kwargs

我基本上想運行從功能字典收集的任務。 我在程序中使用了asyncio,但這對我的問題可能並不重要。 這是我的代碼來說明...

import asyncio
import random


async def faketask(taskname):    # This is a function to simulate asynchronous tasks being performed.
    fakedelay = random.randint(1,6)
    print(f'{taskname} started (completing in {fakedelay} seconds)')
    await asyncio.sleep(fakedelay)
    print(f'{taskname} completed after {fakedelay} seconds')


async def main():
    tasklist = {    # This is a dict of tasks to be performed
    'Task-1': faketask,
    'Task-2': faketask,
    'Task-3': faketask,
    }

    _tasks = []
    for taskname in tasklist:
        _tasks.append(asyncio.ensure_future(tasklist[taskname](taskname)))
        print(f'Added {taskname} to job queue.')
    await asyncio.gather(*_tasks)


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

效果很好。 但是我想定期重復執行某些任務,因此我向faketask函數添加了一些代碼。

async def faketask(taskname, interval=None):
    fakedelay = random.randint(1,6)
    print(f'{taskname} started (completing in {fakedelay} seconds)')
    await asyncio.sleep(fakedelay)
    print(f'{taskname} completed after {fakedelay} seconds')
    if interval is not None:
        print(f'Repeating {taskname} in {interval} seconds')
        while True:
            await faketask(taskname, *args, **kwargs)
            await asyncio.sleep(interval)

通過為kwarg interval提供一個整數,使函數重復執行。 將來的功能可能還會使用其他* args和** kwargs。

所以我基本上希望我可以在任務列表字典中指定重復間隔,例如

    tasklist = {
    'Task-1': faketask,
    'Task-2': faketask,
    'Task-3': faketask(interval=60),
    }

但這是行不通的,因為faketask()缺少1個必需的位置參數:“ taskname”。

有什么聰明的方法可以解決這個問題嗎?

作為一個額外的問題, _tasks.append(asyncio.ensure_future(tasklist[taskname](taskname)))看起來有點難看,有沒有辦法自動傳遞taskname參數?

您可以使用functools.partial ,它是專門為以下情況而設計的:

'Task-3': functools.partial(faketask, interval=60),

作為一個額外的問題, _tasks.append(asyncio.ensure_future(tasklist[taskname](taskname)))看起來有點難看,有沒有辦法自動傳遞taskname參數?

您可以使用items()刪除冗余:

tasks = []
for taskname, taskfn in tasklist.items():
    tasks.append(taskfn(taskname))

不需要顯式調用asyncio.ensure_future ,因為asyncio.gather會自動執行此操作。 另外,我改名_tasks只是tasks 按照慣例,變量名前面的_表示該變量將不會在后續代碼中使用,在這里不是這種情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM