【问题标题】:How do I create a custom cycling status in discord.py?如何在 discord.py 中创建自定义骑行状态?
【发布时间】:2021-04-27 06:43:28
【问题描述】:

我有一个 discord 机器人,我用它来学习如何使用 API 和练习我的 Python 知识。我正在尝试创建一个随机选择状态并应用它的系统,然后等待很短的时间,目前为 10 分钟,然后无限继续,直到机器人关闭。目前,我的on_ready() 函数中有循环,但机器人在短时间内(不到 10 分钟,大约 2-3 分钟)后关闭,我不知道为什么。目前的代码是这样的:

@client.event
async def on_ready():
  print("We have logged in as {0.user}".format(client))
  infiniteTime = 1
  while infiniteTime != 20:
    statusType = random.randint(0, 1)
    if statusType == 0:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.playing, name=playingStatus[statusNum]))
    else:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.watching, name=watchingStatus[statusNum]))
    time.sleep(600)

watchingStatuslisteningStatus 是包含 11 个字符串的一维数组。感谢任何帮助/反馈,因为我是 API 新手。干杯!

ETA:应该澄清一下,我已经意识到在on_ready() 函数中包含代码意味着它永远不会结束,因此不能做任何其他事情。我之所以问,是因为我不知道为什么机器人会在不停止代码的情况下在 Discord 结束时关闭,而且我不知道我应该把这个循环放在哪里,因为我是这个 async/await 系统的新手,并且API 功能的方式。

【问题讨论】:

标签: python python-3.x discord discord.py


【解决方案1】:

您尝试更改机器人状态的地方是正确的,问题是尝试创建此循环的方式正在阻止您的机器人工作,因为time.sleep 不适合异步库,例如不和谐.py。相反,您可以使用asyncio.sleep()

你可以这样做:

import asyncio

@client.event
async def on_ready():
  # ...
  # Here goes your code for on_ready()
  # ...
  while True:
    statusType = random.randint(0, 1)
    if statusType == 0:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.playing, name=playingStatus[statusNum]))
    else:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.watching, name=watchingStatus[statusNum]))
    asyncio.sleep(600)

另一种方法是使用discord.ext.tasks,这些函数定义为运行您想要实现的后台任务。

from discord.ext import commands, tasks
import asyncio

# Your code here

@loop(seconds=600)
async def status_change():
    # ...
    # Some code to define playingStatus and watchingStatus arrays
    # ...
    statusType = random.randint(0, 1)
    if statusType == 0:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.playing, name=playingStatus[statusNum]))
    else:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.watching, name=watchingStatus[statusNum]))

status_change.before_loop(client.wait_until_ready())    
status_change.start()
client.run("TOKEN")

参考资料:

【讨论】:

  • 两种方法都出现错误。第一次启动并正确登录,但随后表示从未等待“睡眠”并启用 tracemalloc 以获取回溯 (screenshot)。第二个表示未定义名称“循环”(screenshot)。有什么想法吗?
  • 我的错,因为您的代码难以重现,我无法测试它是否完全正常工作。对于第一个,您需要等待睡眠:await asyncio.sleep(600)。对于第二种方法,您可能需要使用 from tasks import loop 显式导入循环。
  • 这工作,谢谢!抱歉,它很难重现,它很笨拙,所以有点难以确定!
猜你喜欢
  • 2021-03-01
  • 2020-05-20
  • 2021-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
相关资源
最近更新 更多