python装饰器中decorator用法实例教程

发布时间:2020-07-28编辑:脚本学堂
本文介绍了python装饰器中decorator的用法,Python装饰器的例子,python中装饰器、python装饰器用途,以及python装饰器logger的实现方法,需要的朋友参考下。

python装饰器decorator用法,通过实例学习python装饰器与相关概念用途,一起来了解下。

python装饰器decorator用法

1、闭包(closure)
闭包是Python所支持的一种特性,它让在非global scope定义的函数可以引用其外围空间中的变量,这些外围空间中被引用的变量叫做这个函数的环境变量
环境变量和这个非全局函数一起构成了闭包。

例子:
 

复制代码 代码示例:
def outer(x):
    y = [1,2,3]
    def inner():
        print x
        print y
    return inner
x = 5    #这个x没有被引用
f = outer(2)
f()

print f.__closure__   #函数属性__closure__存储了函数的环境变量 def entrance(func):
 = 5    #这个x没有被引用f = outer(2)f()print f.__closure__   #函数属性__closure__存储了函数的环境变量 def entrance(func):
x和y都是属于函数outer命名空间的,在inner中被引用,当outer函数退出后,outer的命名空间不存在了,但是inner依然维护了其定义时候对其外部变量x,y的连接。

程序输出:
  2
  [1, 2, 3]
  (, )
装饰器是一个可调用对象(a callable),在Python中,函数是对象,当然也是可调用的,所以装饰器可以是一个函数,我们称其为函数装饰器。
这个可调用对象以一个函数作为参数,闭且返回另一个函数(来替换参数那个函数)。
比如:
 

复制代码 代码示例:
def entrance(func):
     def inner():
         print "inside function :", func.__name__
         func()
     return inner

entrance是一个装饰器,它是一个函数,它可以接收一个函数func作为参数,返回了另一个函数inner。
那为什么叫装饰器了,在返回函数inner()的内部,调用了func(),而且还作了额外的操作,相当于“装饰”了函数func。

如何使用装饰器?
 

复制代码 代码示例:
def fun1():
    pass
fun1 = entrance(fun1)
def fun2():
    pass
fun2 = entrance(fun2)

fun1,fun2的名字都没有变,但是通过调用函数装饰器entrance(),它们已经指向了另一个函数inner(),“装饰了”自己。
@操作符
Python提供的@符号,实质上就是上面做的,对一个函数名进行从新赋值,是语法上的技巧。

以上代码等价于:
 

复制代码 代码示例:
@entrance
def fun1():
    pass
@entrance
def fun2():
    pass
 

2、python装饰器的用途
可以看出装饰器的意义,如果一个函数需要一个功能,如果这个功能可以被使用在很多函数上,或是函数并不是自己实现,那可以写个装饰器来实现这些功能。

以上装饰器entrance,装饰一个函数后,函数被调用时会打印出这个函数的名字。
问题:此装饰器从功能上看,是要可以用来装饰任何函数,但是如果用它来装饰了一个带参数的函数:
 

复制代码 代码示例:
@entrance
 def fun3(x):
     pass

只要不调用fun3,这三行代码是不会让Python解释器报错的,它等价于:
 

复制代码 代码示例:
def fun3(x):
    pass
fun3 = entrance(fun3)
 

定义了一个带参的函数fun3,然后把fun3指向了另一个函数inner(),当然不会有什么错。
 
但是,当使用fun3时,肯定会按照它定义时的样子去使用它,给它传入一个参数。
 

复制代码 代码示例:
>>>fun3(1)
 

这里就会出错了,看看解释器怎么报错的
 

Traceback (most recent call last):
File “decorator.py”, line 23, in www.jb200.com <module>
fun3(1)
TypeError: inner() takes no arguments (1 given)

为什么会这样报错了,fun3已经不是指向它定义时那个函数了,它现在指向了”inner()”,而inner是没有参数的,当然会出错。

解决方法就是修改下inner()的定义,让它可以就收任意个参数即可。
 

复制代码 代码示例:
def entrance(func):
     def inner(*args, **kvargs):
         print "inside function : ", func.__name__
         func(*args, **kvargs)
     return inner

现在,给inner传任意个参数都不会出错了,也就是entrance可以被用来装饰任何一个函数了。

3、python装饰器logger
一个函数被调用时,在日志里记录其名称和被调用的实际参数
 

复制代码 代码示例:
def logger(func):
    def inner(*args, **kvargs):
        print  func.__name__, 'called, arguments: ', args, kvargs
        func(*args, **kvargs)
    return inner

以上就是python装饰器中decorator用法教程,希望对大家有所帮助。