python装饰器终极奥义

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { margin: 0; padding: 0; border: 0 }
body { font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px; line-height: 1.6; color: #333; background-color: #fff; padding: 20px; max-width: 960px; margin: 0 auto }
body>*:first-child { margin-top: 0 !important }
body>*:last-child { margin-bottom: 0 !important }
p,blockquote,ul,ol,dl,table,pre { margin: 15px 0 }
h1,h2,h3,h4,h5,h6 { margin: 20px 0 10px; padding: 0; font-weight: bold }
h1 tt,h1 code,h2 tt,h2 code,h3 tt,h3 code,h4 tt,h4 code,h5 tt,h5 code,h6 tt,h6 code { font-size: inherit }
h1 { font-size: 28px; color: #000 }
h2 { font-size: 24px; border-bottom: 1px solid #ccc; color: #000 }
h3 { font-size: 18px }
h4 { font-size: 16px }
h5 { font-size: 14px }
h6 { color: #777; font-size: 14px }
body>h2:first-child,body>h1:first-child,body>h1:first-child+h2,body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child { margin-top: 0; padding-top: 0 }
a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6 { margin-top: 0; padding-top: 0 }
h1+p,h2+p,h3+p,h4+p,h5+p,h6+p { margin-top: 10px }
a { color: #4183C4; text-decoration: none }
a:hover { text-decoration: underline }
ul,ol { padding-left: 30px }
ul li>:first-child,ol li>:first-child,ul li ul:first-of-type,ol li ol:first-of-type,ul li ol:first-of-type,ol li ul:first-of-type { margin-top: 0px }
ul ul,ul ol,ol ol,ol ul { margin-bottom: 0 }
dl { padding: 0 }
dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px }
dl dt:first-child { padding: 0 }
dl dt>:first-child { margin-top: 0px }
dl dt>:last-child { margin-bottom: 0px }
dl dd { margin: 0 0 15px; padding: 0 15px }
dl dd>:first-child { margin-top: 0px }
dl dd>:last-child { margin-bottom: 0px }
pre,code,tt { font-size: 12px; font-family: Consolas, "Liberation Mono", Courier, monospace }
code,tt { margin: 0 0px; padding: 0px 0px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8 }
pre>code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent }
pre { background-color: #f8f8f8; border: 1px solid #ccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px }
pre code,pre tt { background-color: transparent; border: none }
kbd { background-color: #DDDDDD; background-image: linear-gradient(#F1F1F1, #DDDDDD); background-repeat: repeat-x; border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD; border-style: solid; border-width: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 10px; padding: 1px 4px }
blockquote { border-left: 4px solid #DDD; padding: 0 15px; color: #777 }
blockquote>:first-child { margin-top: 0px }
blockquote>:last-child { margin-bottom: 0px }
hr { clear: both; margin: 15px 0; height: 0px; overflow: hidden; border: none; background: transparent; border-bottom: 4px solid #ddd; padding: 0 }
table th { font-weight: bold }
table th,table td { border: 1px solid #ccc; padding: 6px 13px }
table tr { border-top: 1px solid #ccc; background-color: #fff }
table tr:nth-child(2n) { background-color: #f8f8f8 }
img { max-width: 100% }

python装饰器

定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能
原则:
1. 不能修改被装饰的函数的源码
2. 不能修改原函数的调用方式
知识储备:1. 函数即变量函数执行的时候解释器从上向下执行2. 高阶函数
a. 把一个函数名当作实参传递给另一个函数(可以做到在不修改函数源码的情况下,为其添加功能) b. 返回值中包含函数名3. 嵌套函数
当装饰器需要参数需要三层嵌套,不需要参数两层嵌套

装饰器可能的应用

作为一个函数

创造装饰器最简单的方法就是写一个函数,返回包装原始函数调用的一个子函数

def mydecorator(function):      def wrapped(*args,**kwargs):          #调用原始函数之前做的操作          result=function(*args,**kwargs)          #调用原始函数之后做点什么          #返回结果          return result      #返回wrapper作为装饰函数      return wrapped

作为一个类

大多数情况装饰器总是用函数实现,但在某些情况下使用类会更好。如果装饰器需要复杂的参数化或者依赖特定状态,就会使用装饰类
通用模式

class DecoratorAsClass:      def __init__(self,function):           self.function=function      def __call__(self,*args,**kwargs):          #在调用原始函数指点,做点什么          result=self.function(*args,**kwargs)          #在调用原始函数之后做点什么          #返回函数执行结果          return result@DecoratorAsClassdef hello():    print(‘hello‘)hello()

参数化装饰器

实际使用装饰器需要使用参数化的装饰器。类装饰器不用说,初始化的时候就可以传入参数。如果是函数作装饰器的话,就需要第二层包装。如需要多次执行一个原始函数,而重复次数通过装饰器参数给定,下面是示例代码

def repeat(number=3):      """多此执行装饰函数,返回最后一次执行结果       参数名为 number:重复次数,默认为3    """      def erceng_decorator(function):        def wrapper(*args,**kwargs):            result=None              for _ in range(number):                result=function(*args,**kwargs)            return result        return ercent_decorator@repeat(2)def hello():    print("hello")hello()hellohello  

在使用参数化装饰器的时候参数有默认值,但名字后面必须加括号,否则会报错

保存内省的装饰器

在使用装饰器常见的问题就是无法保存原始函数的元数据(文档字符串和函数名),装饰器组合创建了一个新的函数,返回一个新的对象,但没有考虑到原始函数的标识。这回给调试造成麻烦,无法找寻原始函数,也会破坏自动生成文档的工具,无法访问原始函数的文档字符串

def dummy_dec(function):...     def wrapped(*args,**kwargs):...             """包装函数内部文档。"""...     return wrapped   @dummy_dec... def function_important_doc():...     """这是重要文档""" function_important_doc.__name__‘wrapped‘>>> function_important_doc.__doc__‘包装函数内部文档。‘

如上所示,原始函数的名字和文档都被修改了,解决这个问题也很容易,使用functools模块内置的wraps()装饰器:

from functools import wraps  def chuli_dec(function):    @wraps(function)    def wrapper(*args,**kwargs):        """包装函数文档"""        return function(*args,**kwargs)    return wrapper@chuli_decdef func_import_doc():    """这是重要文档"""print(func_import_doc.__name__)print(func_import_doc.__doc__)  func_import_doc这是重要文档

像上面处理这就对了

原文地址:https://www.cnblogs.com/dcotorbool/p/8158008.html

时间: 2024-09-30 15:18:51

python装饰器终极奥义的相关文章

5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器

一.什么是装饰器? 实际上装饰器就是个函数,这个函数可以为其他函数提供附加的功能. 装饰器在给其他函数添加功能时,不会修改原函数的源代码,不会修改原函数的调用方式. 高阶函数+函数嵌套+闭包 = 装饰器 1.1什么是高阶函数? 1.1.1函数接收的参数,包涵一个函数名. 1.1.2 函数的返回值是一个函数名. 其实这两个条件都很好满足,下面就是一个高阶函数的例子. def test1(): print "hamasaki ayumi" def test2(func): return t

python装饰器通俗易懂的解释!

python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说明一下: 小P闲来无事,随便翻看自己以前写的一些函数,忽然对一个最最最基础的函数起了兴趣: 1 def sum1(): 2 sum = 1 + 2 3 print(sum) 4 sum1() 此时小P想看看这个函数执行用了多长时间,所以写了几句代码插进去了: 1 import time 2 3 def

python装饰器1

第八步:让装饰器带 类 参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # -*- coding:gbk -*- '''示例8: 装饰器带类参数''' class locker:     def __init__(self):         print("locker.__init__() should be not called.")   

Python装饰器由浅入深

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

python 装饰器学习(decorator)

最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initial decorator" f() def __call__(self): print "call decorator" @decorator def fun(): print "in the fun" print "after " fun

【转】九步学习python装饰器

本篇日志来自:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 纯转,只字未改.只是为了学习一下装饰器.其实现在也是没有太看明白,对于装饰器我就是用的时候找例子,能蒙对,但是用过之后一段时间就忘了.还是用的少.有空应该好好看一看的,包括闭包.对于各种现代编程语言来说闭包都是很重要的.在这里先谢过原作者,如有侵权请告知. =-=-=-=-=-=-=-=-=-=-一条不怎么华丽的分隔线-=-=-=-=-=-=-=-=-=-= 这

【Python之旅】第四篇(一):Python装饰器

有时候拿到一个程序接口,需要对其进行扩展,但是又不能修改原来接口的源代码,这时候就需要使用装饰器了. 有下面一个小程序,假如是别人提供给我们的调用接口: import time def sayHi():         time.sleep(1)         print 'Hello, I am xpleaf.' 一般情况下,如果想要计算该程序的执行时间(因为有可能要对该接口进行某些性能上的测试),就需要把以上接口修改为下面这样,同时执行一下: 程序代码: import time def s

python装饰器原理及相关操作

python装饰器,简单的说就是用于操作底层代码的代码,在不改变底层代码函数的情况下对底层代码进行验证操作等 首先,必须知,道调用func和func的区别,分别为返回函数所在的内存地址和调用该函数,输出执行结果,例如: def func(): print("欢迎光临!!!") print("返回函数所在的内存地址:",func) func() 列举一个简单的web页面调用例子 1 #做登录验证 2 def login(func): 3 print("登录成

python装饰器学习笔记

什么是python装饰器? 装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符,并永久丧失对原始函数对象的访问. eg:当需要在Func1和Func2中加一样的功能时,可以在outer中添加一次就可以完成全部函数的添加.装饰器与函数建立连接的方式是在函数的前一行用@+装饰器名称来完成.并且在装饰器中一定要返回被装饰的对象 def outer(fun):     def wrapper():         print '验证'