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

时间: 2024-10-31 19:05:10

Python装饰器decorator的简单示例的相关文章

python装饰器decorator介绍_python

一.装饰器decorator decorator设计模式允许动态地对现有的对象或函数包装以至于修改现有的职责和行为,简单地讲用来动态地扩展现有的功能.其实也就是其他语言中的AOP的概念,将对象或函数的真正功能也其他辅助的功能的分离. 二.Python中的decorator python中的decorator通常为输入一个函数,经过装饰后返回另一个函数.  比较常用的功能一般使用decorator来实现,例如python自带的staticmethod和classmethod. 装饰器有两种形式:

Python装饰器详解

装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 装饰器最早在Python 2.5中出现,它最初被用于加工函数和方法这样的可调用对象(callable object,这样的对象定义有__call__方法).在Python 2.6以及之后的

九步学会Python装饰器

  本文实例讲述了Python装饰器.分享给大家供大家参考.具体分析如下: 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次''' def myfunc(): print("myfunc() called.") myfunc() myfunc() 第二步:使用装饰函数在函数执行前和执行后分别附加额外功能 ?

对Python装饰器的个人理解方法

0.说明                   在自己好好总结并对Python装饰器的执行过程进行分解之前,对于装饰器虽然理解它的基本工作方式,但对于存在复杂参数的装饰器(装饰器和函数本身都有参数),总是会感到很模糊,即使这会弄懂了,下一次也很快忘记,其实本质上还是没有多花时间去搞懂其中的细节问题.         虽然网络上已经有很多这样的文章,但显然都是别人的思想,因此自己总是记不牢,所以花点时间自己好好整理一下.         最近在对<Python核心编程>做总结,收获了不少,下面分享

Python 装饰器学习以及实际使用场景实践

前言 前几天在看Flask框架,,不是非常的理解,回来补装饰器的功课.阅读很多的关于装饰器的文章,自己整理一下,适合自己的思路的方法和例子,与大家分享. app = Flask(__name__)  @app.route("/")  def hello():  return "Hello World!"  1.装饰器是什么 装饰器是Python语言中的高级语法.主要的功能是对一个函数.方法.或者类进行加工,作用是为已经存在的对象添加额外的功能,提升代码的可读性. 装

使用Python装饰器在Django框架下去除冗余代码的教程_python

 Python装饰器是一个消除冗余的强大工具.随着将功能模块化为大小合适的方法,即使是最复杂的工作流,装饰器也能使它变成简洁的功能. 例如让我们看看Django web框架,该框架处理请求的方法接收一个方法对象,返回一个响应对象:   def handle_request(request): return HttpResponse("Hello, World") 我最近遇到一个案例,需要编写几个满足下述条件的api方法:     返回json响应     如果是GET请求,那么返回错误

详解Python装饰器由浅入深_python

装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们以装饰函数为例子介绍其用法.要理解在Python中装饰器的原理,需要一步一步来.本文尽量描述得浅显易懂,从最基础的内容讲起. (注:以下使用Python3.5.1环境) 一.Python的函数相关基础 第一,必须强调的是python是从上往下顺序执行的,而且碰到函数的定义代码块是不会立即执行它的,只

Python 装饰器的学习重点

装饰器基础 Python的函数是对象 为了理解装饰器, 你必须先理解: 在Python的世界, 函数是对象. 这一点很重要. 让我们通过一个简单的例子来看看为什么: def shout(word="yes"):     return word.capitalize()+"!" print shout() # 输出 : 'Yes!' # 作为一个对象, 你可以像任何其他对象一样, 将函数赋值给一个变量 scream = shout # 注意, 我们并没有使用括号: #

Python 装饰器一看就懂

讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切. 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,让它变得更厚更长,这样一来,它不仅有遮羞功能,还能提供保暖,不过有个问题,这个内裤被我们改造成了长裤后,虽然还有遮羞功能,但本质上它不再是一条真正的内裤了.于是聪明的人们发明长裤,在不影响内裤的前提下,直接把长裤套在了内裤外面,这样内裤还是内裤,有了长裤后宝宝再也不冷了.装饰器就像我们这里说的长裤,在不