装饰器类和装饰器函数之间的区别

Jul*_*era 11 python syntax decorator

我想这就是它们的调用方式,但我会举例说明以防万一.

装饰者类:

class decorator(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print 'something'
        self.func(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

装饰功能:

def decorator(func):
    def wrapper(*args, **kwargs):
        print 'something'
        return func(*args, **kwargs)
    return wrapper
Run Code Online (Sandbox Code Playgroud)

使用其中一个只是一个品味的问题?有什么实际区别吗?

Joc*_*zel 13

如果你可以编写一个函数来实现你的装饰器,你应该更喜欢它.但并非所有装饰器都可以轻松编写为函数 - 例如,当您想要存储某些内部状态时.

class counted(object):
    """ counts how often a function is called """
    def __init__(self, func):
        self.func = func
        self.counter = 0

    def __call__(self, *args, **kwargs):
        self.counter += 1
        return self.func(*args, **kwargs)


@counted
def something():
    pass

something()
print something.counter
Run Code Online (Sandbox Code Playgroud)

我见过人们(包括我自己)经历了荒谬的努力,只能用函数编写装饰器.我仍然不知道为什么,一个班级的开销通常完全可以忽略不计.

  • 当然这*可以*作为函数编写.但是在Python中,你通常更喜欢一个类而不是闭包来隐藏状态. (4认同)
  • 我实际上喜欢这个的Python(3.x)版本(使用大括号\ * sob \ *,因为注释会吃掉换行符):`def counted(f){x = 0; def wrapper(* args,** kwargs){非本地x; x + = 1; f(* args,** kwargs)}返回包装器}`。2.x版本很丑陋(使用单例列表并使用单个项来解决缺少`nonlocal`的问题)。 (2认同)