我正在构建一个脚本,它有多个任务循环,间隔不同。 自然地,我想制作一个 for 循环来定义所有这些,以使其占用更少的空间。 但是,似乎不可能这样做。
我怎样才能缩短这个片段? 真的有办法吗?
timeloops = ["60","600","3600","7200","14400","21600"]
@tasks.loop(seconds=60)
async def task_60(self):
await second_func(self,channels["60"])
@tasks.loop(seconds=600)
async def task_600(self):
await second_func(self,channels["600"])
@tasks.loop(seconds=3600)
async def task_3600(self):
await second_func(self,channels["3600"])
@tasks.loop(seconds=7200)
async def task_7200(self):
await second_func(self,channels["7200"])
@tasks.loop(seconds=14400)
async def task_14400(self):
await second_func(self,channels["14400"])
@tasks.loop(seconds=21600)
async def task_21600(self):
await second_func(self,channels["21600"])
这里的另一个问题让我使用 Globals,但似乎这只是为了调用函数,而不是定义它。
提前致谢。
答案 0 :(得分:0)
我无法对此进行测试,因为您没有提供 MRE,但我认为将它们构建为列表应该是可行的:
task_loops = [
tasks.loop(seconds=int(secs))(
lambda self, secs=secs: (
await second_func(self.channels[secs]) for _ in '_'
).__anext()
) for secs in timeloops
]
我有点模糊的部分是您是否可以以这种方式定义异步 lambda。这也应该有效:
task_loops = []
for secs in timeloops:
@tasks.loop(seconds=int(secs))
async def task_secs(self, secs=secs):
await second_func(self, channels[secs])
task_loops.append(task_secs)
答案 1 :(得分:0)
如果你真的需要它们作为你的类的方法,那么你可以通过创建你的任务方法的参数化版本来让它工作:
async def timed_task(self, t):
await second_func(self, channels[t])
然后使用 functools.partialmethod
函数创建方法的各个实例(可能将其放在类的 __init__
中):
from functools import partialmethod
for t in timeloops:
# Create the tasks.loop wrapper
wrapper = tasks.loop(seconds=int(t))
# Create the method to be wrapped
wrapped = partialmethod(timed_task, t)
setattr(self, f"task_{t}", wrapper(wrapped))
答案 2 :(得分:0)
您可以使用 exec
来执行函数定义并使用字符串格式来填充变量。你可以试试下面的代码。
import inspect
timeloops = ["60", "600", "3600", "7200", "14400", "21600"]
for i in timeloops:
define_func = f"""
@tasks.loop(seconds=int(i))
async def task_{i}(self):
await second_func(self,channels[f"{i}"])
"""
define_func = inspect.cleandoc(define_func)
exec(define_func)
或者更简单的方法
timeloops = ["60", "600", "3600", "7200", "14400", "21600"]
for i in timeloops:
@tasks.loop(seconds=int(i))
async def task(self, i=i): # Prevent variable i from being overwritten
await second_func(self,channels[i])
exec(f'task_{i}=task')