您当前的位置: 首页 > 网站编程 > PHP教程 > Python装饰器decorator的简单示例

Python装饰器decorator的简单示例

作者:不详 来源:网络 发布时间: 2014-08-11 20:54 点击:
1,闭包(closure) 闭包是Python所支持的一种特性,它让在非global scope定义的函数可以引用其外围空间中的变量,这些外围空间中被引用的变量叫做这个函数的环境变量。环境变量和这个非全局函数一起构成了闭包。 代码如下 def outer(x): y = [1,2,3] def inner(): print

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(),“装饰了”自己。

  @操作符 www.111cn.net

  Python提供的@符号,实质上就是上面做的,对一个函数名进行从新赋值,是语法上的技巧。所以上面的代码等价于

  

  

  

  

  

  

  

  

  

  

  
代码如下


  @entrance

  def fun1():

     pass

  @entrance

  def fun2():

     pass

  


  装饰器的用途?

  从这个刻意构造的很简单的例子,可以看出装饰器的意义,如果一个函数需要一个功能,如果这个功能可以被使用在很多函数上,或是函数并不是自己实现,那可以写个装饰器来实现这些功能。

  上面的装饰器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.111cN.net <module>

  fun3(1)

  TypeError: inner() takes no arguments (1 given)

  


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

  那怎么解决呢?

  修改一下inner()的定义,让它可以就收任意个参数就可以了 【注:参见Python函数一文】

  

  

  

  

  

  

  

  

  

  

  
代码如下


  def entrance(func):

  2    def inner(*args, **kvargs):

          print "inside function : ", func.__name__

          func(*args, **kvargs)

      return inner

  


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

  3,写个装饰器logger

  一个函数被调用时,在日志里记录其名称和被调用的实际参数

  

  

  

  

  

  

  

  

  

  

  
代码如下


  def logger(func):

     def inner(*args, **kvargs):

         print func.__name__, 'called, arguments: ', args, kvargs

         func(*args, **kvargs)

     return inner

  
分享到:
本文"Python装饰器decorator的简单示例"由远航站长收集整理而来,仅供大家学习与参考使用。更多网站制作教程尽在远航站长站。
顶一下
(0)
0%
踩一下
(0)
0%
[点击 次] [返回上一页] [打印]
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
关于本站 - 联系我们 - 网站声明 - 友情连接- 网站地图 - 站点地图 - 返回顶部
Copyright © 2007-2013 www.yhzhan.com(远航站长). All Rights Reserved .
远航站长:为中小站长提供最佳的学习与交流平台,提供网页制作与网站编程等各类网站制作教程.
官方QQ:445490277 网站群:26680406 网站备案号:豫ICP备07500620号-4