Issue
Id like to create a custom command type i guess you'd call it. the idea is every time the command is called it first checks its custom attribute then modifies that same attribute.
here is the code i have so far, though it doesn't work i hope it demonstrates what im trying to do.
class Perc(commands.Command):
def __init__(self , func , basePrice = 10):
super().__init__(func)
self.basePrice : int = basePrice
async def __call__(self, *args, **kwargs):
# modify base price
self.basePrice += 10
return await super().__call__(*args, **kwargs)
@Perc(basePrice = 25)
async def testPerc(ctx : commands.Context):
await ctx.send("command called")
Solution
You need to make the factory function that returns the new class. To decorate a function, you need @decorator(args)
which does (decorator(args))(func)
. This is why __call__
does not work.
If you look at the source code here, at line 498, you have __call__(self, context: Context[BotT], /, *args: P.args, **kwargs: P.kwargs) -> T:
. You can see that this is not the creation of a decorator, but rather actually calling the object.
There is a better way to do this, using before_invoke
.
@dataclass
class Perc:
basePrice: int
price = Perc(basePrice=25)
@commands.command(name='perc')
async def perc(ctx):
await ctx.send(f'I have finished the command: {price}.')
async def before_perc(ctx):
price.basePrice += 10
await ctx.send('I have finished before_invoke')
perc.before_invoke(before_perc)
client.add_command(perc)
This makes before_perc
execute right before executing the command. This is where you can add your logic such as increasing the base price.
Answered By - Eric Jin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.