1、装饰器的本质是函数,主要用来装饰其他函数,也就是为其他函数添加附加功能

2、装饰器的原则:

(1) 装饰器不能修改被装饰的函数的源代码

(2) 装饰器不能修改被装饰的函数的调用方式

3、实现装饰器的知识储备

(1) Python中函数即‘变量’

a、变量在Python中的存储
  1. x='Tomwenxing'
  2. y=x

[说明]:

当Python解释器遇到语句x='Tomwenxing'时,它主要完成了两样工作:

  1.在内存中开辟了一片空间用来存储字符串‘Tomwenxing’

  2.在内存从创建了一个名为x的变量,并用它指向字符串‘Tomwenxing’所占据的内存空间(可以理解为房间和房间号的关系)

而语句y=x意为将变量x对字符串的引用赋值给变量y,即在内存中创建一个变量y,并使其指向变量x所指向的内存空间

b、函数在Python中的存储
  1. def test():
  2. pass

[说明]:

在Python中,函数的存储和变量相似,以上面的函数为例,Python解释其主要做两件事:

  1.在内存中开辟一个内存空间,用来存储函数代码的字符串(本例中代码只有一句:pass)

  2.在内存中创建一个变量test,用来指向存储函数代码字符串的内存空间(相当于test=‘函数体’)

因此说在Python中函数即变量

(2) 高阶函数(下面两个条件满足任何一个即为高阶函数)

a、把一个函数名当做实参传递给另外一个函数

[对装饰器的影响]:达到“在不修改被装饰函数源代码的情况下为其添加功能”的效果

  1. import time
  2. def bar():
  3. time.sleep(2)
  4. print('in the bar')
  5.  
  6. def test(func):
  7. start_time=time.time()
  8. func()
  9. stop_time=time.time()
  10. print('函数的运行时间为:',stop_time-start_time)
  11.  
  12. test(bar)

b、返回值中包含函数名

[对装饰器的影响]:达到“不改变函数的调用方式“的效果

  1. import time
  2. def bar():
  3. time.sleep(3)
  4. print('in the bar')
  5.  
  6. def test2(func):
  7. print('新添加的功能')
  8. return func
  9.  
  10. bar=test2(bar)
  11. bar()

(3) 嵌套函数:在一个函数体内用def去声明一个新的函数(不是调用)

  1. def foo():
  2. print('in the foo')
  3. def bar(): #声明一个新的函数,而不是调用函数
  4. print('in the bar')
  5. bar()
  6.  
  7. foo()

4、装饰器的语法:高阶函数+嵌套函数=》装饰器 (下面的例子可以用pycharm的调试器调试一下,看看代码的运行顺序)

  1. import time
  2. def timer(func):
  3. def deco(*args,**kwargs):#使用了不定参数
  4. start_time=time.time()
  5. res=func(*args,**kwargs) #运行函数
  6. stop_time=time.time()
  7. print('运行时间:',stop_time-start_time)
  8. return res # 若无返回值,则返回None
  9. return deco
  10.  
  11. @timer #等价于test1=timer(test1)=deco,即test1()=deco()
  12. def test1():
  13. time.sleep(3)
  14. print('in the test1')
  15.  
  16. @timer #等价于test2=timer(test2)=deco,即test2(name)=deco(name)
  17. def test2(name):
  18. time.sleep(3)
  19. print('in the test2',name)
  20.  
  21. test1()
  22. print('-------------分界线------------------------')
  23. test2('Tomwenxing')

5、带参数的装饰器

  1. user,passwd='Tomwenxing',''
  2. #如装饰器带参数,一般是三层嵌套
  3. def auth(auth_type): #第一层的参数是装饰器的参数
  4. def outer_wrapper(func):#第二层的参数是装饰器要装饰的目标函数
  5. def wrapper(*args,**kwargs):#第三次的参数是目标函数的参数
  6. if auth_type=='local':
  7. username = input('Username:').strip()
  8. password = input('Password:').strip()
  9. if user == username and passwd == password:
  10. print('用户Tomwenxing已经成功登录!')
  11. res = func(*args, **kwargs) #运行目标函数
  12. return res
  13. else:
  14. exit('用户名或密码有错误')
  15. elif auth_type=='ldap':
  16. print('暂不支持这种登录方式!')
  17. return wrapper
  18. return outer_wrapper
  19.  
  20. def index():
  21. print('欢迎来到index页面')
  22.  
  23. @auth(auth_type='local') #home=wrapper()
  24. def home(name):
  25. print('%s,欢迎来到home页面' %name)
  26. return 'This is home page'
  27.  
  28. @auth(auth_type='ldap')
  29. def bbs():
  30. print('欢迎来到bbs页面 ')
  31.  
  32. index()
  33. print('----------------------分界线-------------------')
  34. print('函数的返回值为:',home('wenxing'))
  35. print('----------------------分界线-------------------')
  36. bbs()

Python:装饰器的简单理解的更多相关文章

  1. python装饰器的简单理解

    如果你接触 Python 有一段时间了的话,想必你对 @ 符号一定不陌生了,没错 @ 符号就是装饰器的语法糖. 装饰器的使用方法很固定: 先定义一个装饰函数(帽子)(也可以用类.偏函数实现) 再定义你 ...

  2. Python装饰器的通俗理解

    转载:http://blog.csdn.net/u013471155 在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略 ...

  3. (一)Python装饰器的通俗理解

    在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略有领悟,我希望以下的内容会对你有帮助,我也努力通过通俗的方式使得对Py ...

  4. 个人关于python装饰器的白痴理解

    无参数装饰器 对于python小白来说,python的装饰器简直让人懵逼,不知如何理解,其实按照装饰器的字面意思, 就是把自己定义的函数装饰一遍,然后返回一个新的函数(注意是新的,已经不是本来定义的函 ...

  5. Python装饰器的深入理解

    装饰器 #装饰器:本质上是函数,(装饰其他函数)就是为其他函数添加附加功能 #原则: 1.不能修改被装饰的函数的源代码 # 2.不能修改被装饰的函数的调用方式 #实现装饰器知识储备 #1.函数即变量 ...

  6. python 装饰器的详细理解【多次实验】

    demo: # 装饰器其实就是对闭包的使用 print('haha嘻嘻') def hot(): print('知道') def dec(fun): print("call dec" ...

  7. http://python.jobbole.com/85056/ 简单 12 步理解 Python 装饰器,https://www.cnblogs.com/deeper/p/7482958.html另一篇文章

    好吧,我标题党了.作为 Python 教师,我发现理解装饰器是学生们从接触后就一直纠结的问题.那是因为装饰器确实难以理解!想弄明白装饰器,需要理解一些函数式编程概念,并且要对Python中函数定义和函 ...

  8. python 装饰器、内部函数、闭包简单理解

    python内部函数.闭包共同之处在于都是以函数作为参数传递到函数,不同之处在于返回与调用有所区别. 1.python内部函数 python内部函数示例: def test(*args): def a ...

  9. 理解Python装饰器

    装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权 ...

随机推荐

  1. 误卸载glibc类库导致系统崩溃解决方案

    由于系统中没有yum环境需要编译安装redis,但系统中却没有安装gcc和gcc-c++,挂载本地镜像安装gcc和gcc-c++由于版本太高,由于一时疏忽误将系统的依赖库glibc使用rpm -e 命 ...

  2. Delphi XE7调用Java Class,JAR

    Delphi XE5,XE6需要用户手工编译并将Classes.Dex加入到包中,不过Delphi XE7可以省掉这些工作了. 如何在XE7中调用Java,具体步骤如下: 1.将jar文件添加到XE7 ...

  3. PE 学习之路 —— 区块表

    1. 前述 在 NT 头结束后,紧接着就是区块表,区块表包含每个块在映象中的信息,分别指向不同的区块实体. 2. 区块表 区块表是一个 IMAGE_SECTION_HEADER 结构数组,这个结构包含 ...

  4. string函数库的原型

    #ifndef __HAVE_ARCH_STRCPY /** * strcpy - Copy a %NUL terminated string * @dest: Where to copy the s ...

  5. day1-exercise

    """ Day1 作业 Isabelle/刘佳赐 October 22, 2018 """ """ 1. 变量 ...

  6. hive的分桶

    套话之分桶的定义: 分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储.对于 hive 中每一个表.分区都可以进一步进行分桶. 列的哈希值除以桶的个数来决定每条数据划分在哪个桶中.(网上其它定 ...

  7. Python使用__slots__限制实例属性

    #定义一个类Student class Student(object): __slots__ = ('name','age') #用元组(tuple)的形式绑定属性名称 s = Student() s ...

  8. python2.7入门---多线程

        多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹 ...

  9. 在linux环境下安装redis并且搭建自己的redis集群

    此文档主要介绍在linux环境下安装redis并且搭建自己的redis集群 搭建环境: ubuntun 16.04 + redis-3.0.6 本文章分为三个部分:redis安装.搭建redis集群 ...

  10. 20155216 2016-2017-2 《Java程序设计》第三周学习总结

    教材学习内容总结 区分基本类型与类类型 类类型是自己定义产生的,基本类型是long,int,double等类型. 在类的定义过程中,可直接用class XXX {}对每个序定义的值域成员进行定义.这样 ...