码迷,mamicode.com
首页 > 编程语言 > 详细

python decorator

时间:2017-08-05 15:40:54      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:例子   方式   ...   简化   问题   round   细节   参数   bsp   

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

标签:例子   方式   ...   简化   问题   round   细节   参数   bsp   

原文地址:http://www.cnblogs.com/gattaca/p/7290296.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!