我想使用两种类型的装饰器:
一)
@new
def foo():
print("foo")
b)
@new(arg1, arg2, arg3, ...)
def bar():
print("bar")
基本上,我想为“新消息”事件创建不同的处理程序。如果您想将其用于所有消息,您应该可以编写 @message.new
或 @message.new(filter)
如果您只希望处理程序覆盖未过滤的处理程序以处理来自某些人员的消息或仅处理带有某些附件的消息。
我的第一个想法是装饰器可以检查它的第一个参数是否是一个函数。如果是,它会猜测它被用作@message.new
。如果第一个参数不是函数,它将返回一个装饰器。
from inspect import isfunction
def new(*args):
x = args[0]
if isfunction(x):
return new_noargs(x)
else:
return gen_new_args(args)
def new_noargs(func):
def munc():
print("new_noargs")
func()
return munc
def gen_new_args(args):
def dec(func):
def zunc():
print("new_args:", args)
func()
return zunc
return dec
它有效:
@new
def foo():
print("foo")
@new(1,2,3)
def bar():
print("bar")
不过,它看起来非常笨拙且不符合Python风格。有更方便的方法来解决我的问题吗?另外,如果我想使用 @new(some_function)
,当前的 new
方法将决定它的调用方式如下:
@new
def some_function():
...
如何改进我的代码?
解决方法
@overengineer
是一个装饰器,允许在不使用括号的情况下调用另一个装饰器。它仍然太复杂,但更可重用。
def overengineer(decorator):
def dec(*args):
x = args[0]
if isfunction(x):
return decorator()(x)
else:
return decorator(*args)
return dec
@overengineer
def new(*args):
def dec(func):
def zunc():
print("args:", args)
func()
return zunc
return dec
最佳答案
我想这个问题的前提是有缺陷的,因为我通过编写 @new()
而不是 @new
并没有损失太多,但我获得了一致性和简单性: new 只是一个装饰器。或者,我可以制作两个不同的装饰器。
关于python - 如何使 @decorator 和 @decorator(args) 共享相同的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54095208/