首先,道歉。我对Python很陌生。我来自Java / C#编码背景。我在很多方面都喜欢Python的简单性,但同时也发现很难确定一些标准。
例如,我已经成功地使Discord Bot运行。异步方法运行良好。但是我想安排一份工作,每30分钟运行一次。但是,当我键入asyncio.run(job())时,Python告诉我“运行”不是asyncio的属性。我真的不确定为什么会这样说。哎呀,异步是做到这一点的“正确”方法吗?
不和谐的导入是否可能以某种方式掩盖了它?我想我可能需要读书或其他东西!
再次感谢。我确实尝试过搜索,但是什么都没有!
答案 0 :(得分:2)
random_order_idx = np.random.permutation(np.arange(len(dups)))
random_dups_deduped = dups.iloc[random_order_idx].drop_duplicates()
pd.concat([uniques, random_dups_deduped])
a dup_flag
0 0 False
1 1 False
3 3 False
6 5 False
7 6 False
5 4 True
2 2 True
在启动discord bot时被调用,因此一种方法是将您的作业附加到它:
on_ready
import discord
import asyncio
client = discord.Client()
@client.event
async def on_ready():
while True:
await asyncio.sleep(30*60) # every 30 minutes
job()
client.run(os.environ.get('DISCORD_BOT_SECRET')) # provide your API token here!!
是 non-blocking 睡眠-如果在此处使用asyncio.sleep
,则漫游器将等待time.sleep
完成,并会对任何传入的其他消息无响应。但是time.sleep
所做的是将控制权返回到事件循环,该事件循环可以处理其他机器人功能。只有在30分钟之后,控制权才会返回到await asyncio.sleep
。
请注意,作业运行时会阻止您的漫游器,这对于任务时间超过几秒钟的作业来说是一个问题。如果您的工作是基于I / O的(例如,获取网站),则可以使用异步I / O操作(例如aiohttp)来保持响应。如果您的作业是基于CPU的,则您可以使用多个进程,例如on_ready
,前提是可以使用终端命令来调用您的作业。
答案 1 :(得分:0)
每30分钟安排一次作业的现代方法是使用discord.ext.tasks
:
import asyncio
import contextlib
import discord
from discord.ext import tasks
client = discord.Client()
@tasks.loop(minutes=30) # every 30 minutes
async def job():
with contextlib.suppress(Exception):
... # your code here
job.start()
client.run(os.environ.get('DISCORD_BOT_SECRET')) # provide your API token here!!
Discord客户端的事件循环每30分钟调用一次函数job()
。这里有几点注意事项:
job()
引发异常,整个循环将停止。是的,不仅是此调用,而且整个循环都将退出。这就是为什么我添加了一个with语句来捕获所有异常的原因,这等效于try: ... except: pass
。job()
正在运行时,机器人的其他部分也被阻止。。这是因为异步不是使用多个线程实现的,而是在单个线程中使用协程的。解决此问题的一种方法可能是使您的代码异步(例如,使用aiohttp
进行Web请求)或使用subprocess.Popen
启动另一个进程。