python decorator

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python decorator相关的知识,希望对你有一定的参考价值。

decorator(装饰器)绝对是Python学习道路上的一个拦路虎。想要理解它,先看两个概念。

nested function(内嵌函数)

def helper(num):
    def is_even(arg):
        return arg % 2 == 0
    if is_even(num):
        print(num, is even)
    else:
        print(num, is odd)

类似于函数局部变量,内嵌函数就是函数的局部函数。

Python的内嵌函数有个特点,它可以访问自身作用域外围的变量。

def helper(num):
    def is_even():
        return num % 2 == 0
    if is_even():
        print(num, is even)
    else:
        print(num, is odd)

内嵌函数is_even可以直接访问外围参数num。

函数可以作为返回值

def helper(type):
    def helper_lower(arg):
        return arg.lower()
    def helper_upper(arg):
        return arg.upper()
    if type == lower:
        return helper_lower
    else:
        return helper_upper

mylower = helper(lower)
print(mylower)
print(mylower(HELLO WORLD))

myupper = helper(upper)
print(myupper)
print(myupper(hello world))

<function helper.<locals>.helper_lower at 0x106aee598>
hello world
<function helper.<locals>.helper_upper at 0x106aee730>
HELLO WORLD

 

现在回到装饰器。

装饰器的作用是,在不改变函数原有实现的基础上,给函数增加新的功能。

举个例子:

def decorator(func):
    print(before the function runs...)
    func()
    print(after the function runs...)
    
def hello():
    print(hello, i am foo)

现在执行decorator(hello),输出如下:

before the function runs...
hello, i am foo
after the function runs...

 

但是有个问题,为了这个新功能,用户需要把所有调用hello的地方换成decorator(hello)。

可以通过返回内嵌函数的方式解决:

def decorator(func):
    def wrapper():
        print(before the function runs...)
        func()
        print(after the function runs...)
    return wrapper

def hello():
    print(hello, i am foo)
    
hello = decorator(hello)
hello()

如果原先的函数hello有参数怎么办呢?

def decorator(func):
    def wrapper(name):
        print(before the function runs...)
        func(name)
        print(after the function runs...)
    return wrapper

def hello(name):
    print(hello, i am, name)
    
hello = decorator(hello)
hello(logan)

参数传递细节

hello(‘logan‘)

decorator(hello)(‘logan‘)

wrapper(‘logan‘)

通用版本的decorator如下:

def decorator(func):
    def wrapper(*args, **kw):
        print(before the function runs...)
        func(*args, **kw)
        print(after the function runs...)
    return wrapper

python为了简化hello = decorator(hello),使用了@符号。

def decorator(func):
    def wrapper(*args, **kw):
        print(before the function runs...)
        func(*args, **kw)
        print(after the function runs...)
    return wrapper

@decorator
def hello(name):
    print(hello, i am, name)

hello(logan)

 






以上是关于python decorator的主要内容,如果未能解决你的问题,请参考以下文章

python之装饰器(decorator)

15-python-decorators

python--decorator装饰器

python decorator的本质

Python – 装饰器(Decorator)

python 装饰器 Decorator