我想使用两种类型的装饰器:
a)
@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")
但是,它看起来非常笨拙且不合常规。有没有更方便的方法来解决我的问题?另外,如果我想使用 @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
答案 0 :(得分:0)
我想这个问题的前提是有缺陷的,因为我写@new()
而不是@new
并不会造成很多损失,但是我获得了一致性和简单性:new只是一个装饰器。另外,我可以制作两个不同的装饰器。