我想使用两种类型的装饰:
a)
@new
def foo():
print("foo")b)
@new(arg1, arg2, arg3, ...)
def bar():
print("bar")基本上,我想为“新消息”事件做不同的处理程序。如果您希望将@message.new用于所有消息,或者只希望处理程序覆盖未经筛选的处理程序来处理来自特定人的消息,或者只使用具有特定附件的消息,则应该能够编写它。
我的第一个想法是,装饰师可以检查它的第一个参数是否是一个函数。如果是的话,它会猜测它被用作@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发布于 2019-01-08 16:56:59
我想这个问题的前提是有缺陷的,因为我不会因为编写@new()而不是@new而损失很多,但是我获得了一致性和简单性: new只是一个修饰器。或者,我可以做两个不同的装饰师。
https://stackoverflow.com/questions/54095208
复制相似问题