首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎样才能让@decorator和@decorator(args)同名呢?

我怎样才能让@decorator和@decorator(args)同名呢?
EN

Stack Overflow用户
提问于 2019-01-08 15:45:55
回答 1查看 107关注 0票数 2

我想使用两种类型的装饰:

a)

代码语言:javascript
复制
@new
def foo():
    print("foo")

b)

代码语言:javascript
复制
@new(arg1, arg2, arg3, ...)
def bar():
    print("bar")

基本上,我想为“新消息”事件做不同的处理程序。如果您希望将@message.new用于所有消息,或者只希望处理程序覆盖未经筛选的处理程序来处理来自特定人的消息,或者只使用具有特定附件的消息,则应该能够编写它。

我的第一个想法是,装饰师可以检查它的第一个参数是否是一个函数。如果是的话,它会猜测它被用作@message.new。如果第一个参数不是函数,它将返回一个装饰器。

代码语言:javascript
复制
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

它的作用是:

代码语言:javascript
复制
@new
def foo():
    print("foo")

@new(1,2,3)
def bar():
    print("bar")

不过,它看上去很笨拙,而且没有节奏感。有没有更方便的方法来解决我的问题?此外,如果我想使用@new(some_function),,那么当前的new方法将决定它被调用如下:

代码语言:javascript
复制
@new
def some_function():
    ...

如何改进我的代码?

解决办法

@overengineer是一个装饰器,它允许不带括号地调用另一个装饰器。它仍然太复杂,但更可重用。

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-08 16:56:59

我想这个问题的前提是有缺陷的,因为我不会因为编写@new()而不是@new而损失很多,但是我获得了一致性和简单性: new只是一个修饰器。或者,我可以做两个不同的装饰师。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54095208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档