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

2、装饰器的原则:

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

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

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

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

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

[说明]:

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

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

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

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

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

[说明]:

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

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

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

因此说在Python中函数即变量

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

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

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

 import time
def bar():
time.sleep(2)
print('in the bar') def test(func):
start_time=time.time()
func()
stop_time=time.time()
print('函数的运行时间为:',stop_time-start_time) test(bar)

b、返回值中包含函数名

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

 import time
def bar():
time.sleep(3)
print('in the bar') def test2(func):
print('新添加的功能')
return func bar=test2(bar)
bar()

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

 def foo():
print('in the foo')
def bar(): #声明一个新的函数,而不是调用函数
print('in the bar')
bar() foo()

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

 import time
def timer(func):
def deco(*args,**kwargs):#使用了不定参数
start_time=time.time()
res=func(*args,**kwargs) #运行函数
stop_time=time.time()
print('运行时间:',stop_time-start_time)
return res # 若无返回值,则返回None
return deco @timer #等价于test1=timer(test1)=deco,即test1()=deco()
def test1():
time.sleep(3)
print('in the test1') @timer #等价于test2=timer(test2)=deco,即test2(name)=deco(name)
def test2(name):
time.sleep(3)
print('in the test2',name) test1()
print('-------------分界线------------------------')
test2('Tomwenxing')

5、带参数的装饰器

 user,passwd='Tomwenxing',''
#如装饰器带参数,一般是三层嵌套
def auth(auth_type): #第一层的参数是装饰器的参数
def outer_wrapper(func):#第二层的参数是装饰器要装饰的目标函数
def wrapper(*args,**kwargs):#第三次的参数是目标函数的参数
if auth_type=='local':
username = input('Username:').strip()
password = input('Password:').strip()
if user == username and passwd == password:
print('用户Tomwenxing已经成功登录!')
res = func(*args, **kwargs) #运行目标函数
return res
else:
exit('用户名或密码有错误')
elif auth_type=='ldap':
print('暂不支持这种登录方式!')
return wrapper
return outer_wrapper def index():
print('欢迎来到index页面') @auth(auth_type='local') #home=wrapper()
def home(name):
print('%s,欢迎来到home页面' %name)
return 'This is home page' @auth(auth_type='ldap')
def bbs():
print('欢迎来到bbs页面 ') index()
print('----------------------分界线-------------------')
print('函数的返回值为:',home('wenxing'))
print('----------------------分界线-------------------')
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. Maven插件的简介,安装及在eclipse中配置

    1.Maven简介 1.Maven介绍 Maven是一个基于项目对象模型(POM:project object model)的概念的纯java开发的开源的项目管理工具.Maven把我们的工程抽像一个对 ...

  2. js身份证校验

    通过js实现对15位或者18位身份证格式校验: 通过调用idCardNoUtil.checkeIdCardNo(idCardNo)传入身份证号码,实现校验. var idCardNoUtil = { ...

  3. 用js实现导出功能将html中的table导出为excel

    /** * 描述:导出表格对应的excel文件 * 时间:2018-03-29 * 作者:任恩远 * 调用示例: * onclick = "tableToExcel(tableId,file ...

  4. PS中10种样式操作

    (1)投影:将为图层上的对象.文本或形状后面添加阴影效果.投影参数由“混合模式”.“不透明度”.“角度”.“距离”.“扩展”和“大小”等各种选项组成,通过对这些选项的设置可以得到需要的效果. (2)内 ...

  5. 手搓一个兔子问题(分享一个C语言问题,持续更新...)

    大家好,我是小七夜,今天就不分享C语言的基础知识了,分享一个比较好玩的C语言经典例题:兔子问题 题目是这样的:说有一个穷苦人这天捉到了一只公兔子,为了能繁衍后代他又买了一只母兔子,后来兔子开始生小兔子 ...

  6. em,rem区别比较

    rem是基于html元素的字体大小来决定,而em则根据使用它的元素的大小决定. 注意:很多人错误以为em是根据父类元素,实际上是使用它的元素继承了父类元素的属性才会产生的错觉. 主要区别 em 和 r ...

  7. 欧几里得算法/欧几里得扩展算法-python

    说在开头. 出于对欧几里得的尊重,先简单介(cou)绍(ge)一(zi)下(shu).. 欧几里得,古希腊人,数学家.他活跃于托勒密一世时期的亚历山大里亚,被称为“几何之父”. 他最著名的著作< ...

  8. IDL返回众数(数组中出现次数最多的值)

    对于整型数组,可以直接利用histogram函数可以实现,示例如下: IDL>array = [1, 1, 2 , 4, 1, 3, 3, 2, 4, 5, 3, 2, 2, 1, 2, 6, ...

  9. 20155204第4次实验《Android程序设计》实验报告

    20155204第四次实验报告 一.实验内容及步骤 1.Android Stuidio的安装测试: 安装 Android Stuidio 完成Hello World, 要求修改res目录中的内容,He ...

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

    20155214 2016-2017-2 <Java程序设计>第3周学习总结 教材学习内容总结 Chapter4 一个原始码中可以有多个类定义,但只能有一个公开类,且文档中的主文档名必须与 ...