python - 对这个 Discord.py Rewrite + Reaction Light 代码感到困惑 - 需要解释
问题描述
因此,虽然我们都知道整个复制和粘贴其他人的代码,并且神奇地工作,但在弄清楚这段代码的实际工作和功能时,它会失去一些上下文和理解。
我正在使用Discord.py Rewrite和一段名为Reaction Light的代码,以创建一个允许在我的Discord Server中自我分配角色的机器人。该机器人 100% 正常运行并按预期工作。现在,我已经从他们的代码中改变了一些东西,所以我的方法位于不同的位置并从不同的区域调用。
这是我感到困惑的地方:
isadmin()
每当需要完成检查以确定发出命令的用户是否是管理员时,我都会调用一个名为 this 的方法。管理员角色在我使用 dotenv 模块检索的 .env 文件中定义。很直接的东西。(我稍后会重写它的那部分,并希望将所有管理员角色 ID 放入一个文件中并从那里获取它们。)但是我对这个方法的第三个参数究竟做了什么感到困惑。msg=False
每当我为此编写 cogs 时,我都会直接调用此方法,而无需将“msg”参数传递给它,如下所示:
# admin.py
# Simple ping pong command
@commands.command()
async def ping(self, ctx):
if helpers.isadmin(ctx):
print("Running Command from admin.py")
await ctx.send('Pong!')
现在在我的on_message()
侦听器方法中,它传递msg
参数,然后执行一些与 ping 命令无关但与机器人的自分配角色部分的功能相关的代码。
# message.py
@commands.Cog.listener()
async def on_message(self, message):
if helpers.isadmin(message, msg=True):
# Execute some code here for the self-assigning roles
据我所知,这个工作流程的工作方式是这样的,我将使用 ping 命令作为该r.ping
命令调用的示例。
- on_message() 侦听服务器中发送的所有消息
- 用户在频道中发出的 Ping 命令
- on_message() 听到消息并检查用户是否是管理员,但也传递
msg
参数 - 从调用 ping 命令
admin.py
,然后检查(再次?)用户是否是管理员,如果他/她是,则执行该命令。
所以,我试图弄清楚何时或何时不使用这个msg
参数,如果它已经在检查用户是否是监听器中的管理员,我是否必须再次检查实际命令本身?是不是有点多余?
这是helpers.py文件isadmin()
中的方法
# helpers.py
def isadmin(self, ctx, msg=False):
# Checks if command author has one of .env admin role IDs
try:
check = (
[role.id for role in ctx.author.roles]
if msg
else [role.id for role in ctx.message.author.roles]
)
if self.admin_a in check or self.admin_b in check or self.admin_c in check:
return True
return False
except AttributeError:
# Error raised from 'fake' users, such as webhooks
return False
解决方案
老实说,我不确定为什么会这样。如果您有权访问,则ctx.author
可以访问该消息的作者,这似乎是多余的。但是,我强烈建议您为此使用检查。例如我有:ctx.message
ctx.author
def is_owner():
def predicate(ctx):
return ctx.author.id in ctx.bot.config()["owners"]
return commands.check(predicate)
我用它作为装饰器
# utils/checks/checks.py
from utils.checks import checks
@checks.is_owner()
@commands.group(hidden=True, case_insensitive=True, description="Load a module")
async def load(self, ctx):
if not ctx.invoked_subcommand:
return await ctx.send_help(ctx.command)
例如你可以有
def is_admin():
def predicate(ctx):
role_id = 123123123123123 # replace this with os.getenv("wherever your admin role is")
return role_id in [x.id for x in ctx.author.roles]
return commands.check(predicate)
在我看来,它更干净,更容易使用/理解。
推荐阅读
- php - 如何从图像结果列表中选择一张图像?
- swift - 将类编码为单个值而不是字典 swift
- php - CentOS PHP 7.4 升级 pecl / pear 包时出错
- python - Matplotlib 共享 y 轴 - 一个子图未对齐
- identityserver3 - 从 Identity Server 3 迁移数据
- sql-server - 带有 SQL Always Encrypted 列的 CI
- python - 如何在子进程模块中引用文件
- firebase - NativeScript Vue - Firebase 在应用重启时重新登录用户
- python - 如何使用 Python 解析嵌套的 JSON
- vue.js - 从插件注册模块时vuex未知动作类型