Python 参数装饰器的用法与实现原理


import functools

第一种

################################################## def require_permission(permissions): def decorated(func): @functools.wraps(func) def wrapper(*args, **kwargs): has_permissions = permissions if has_permissions: return func(*args, **kwargs) else: print(403)

    return wrapper

return decorated

@require_permission(True) def foo(): print(‘foo’)

@require_permission(False) def foo(): print(‘foo’)

第二种

##################################################################### class require_permissions(object): def init(self, permissions): self.permissions = permissions

def __call__(self, fn):
    @functools.wraps(fn)
    def decorated(*args, **kwargs):

        has_permissions = self.permissions

        if has_permissions:
            return fn(*args, **kwargs)
        else:
            print(403)

    return decorated

def require_permission(permission): return require_permissions(permission)

@require_permission(True) def foo1(): print(‘foo’)

if name == ‘main’: foo() foo1()


Python 参数装饰器的用法与实现原理

1 回复

Python的参数装饰器其实就是在普通装饰器外面再套一层,用来接收装饰器自己的参数。

比如我们常用的 @app.route('/path'),这里的 '/path' 就是传给装饰器的参数。

实现原理很简单:

  1. 外层函数接收装饰器的参数(比如 '/path'
  2. 它返回一个内层函数,这个内层函数才是真正的装饰器(接收被装饰的函数)
  3. 内层装饰器返回一个包装函数(或直接返回原函数)

看个例子就明白了:

def repeat(n):
    """外层接收装饰器参数"""
    def decorator(func):
        """内层才是真正的装饰器,接收被装饰函数"""
        def wrapper(*args, **kwargs):
            for _ in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

# 使用
@repeat(3)
def greet(name):
    print(f"Hello, {name}")

greet("World")
# 输出三次 Hello, World

这里 repeat(3) 先执行,返回 decorator,然后 decorator(greet) 返回 wrapper,最终调用的是包装后的函数。

简单说就是三层嵌套函数,外层吃参数,中层吃函数,内层吃函数参数。

回到顶部