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()

最新文章

  1. 198个经典C#WinForm实例源码(超赞) 里面的例子 .sln 目录
  2. 安装和使用sass
  3. 习惯&感恩
  4. Qt 学习之路:模型-视图高级技术
  5. WordPress网站更换老鹰主机详细操作
  6. 关于position和float的用法!
  7. C++, const:
  8. SQL点滴29—错误无处不在
  9. html的块级元素和内联元素
  10. 初窥 MongoDB
  11. 构建微服务开发环境4————安装Docker及下载常用镜像
  12. 基于 HTML5 的 WebGL 3D 档案馆可视化管理系统
  13. springboot 传值到页面
  14. TcxScheduler的使用2
  15. Python如何实现文本转语音
  16. db-mysql-001- 语句备份表
  17. 获取指定包名下继承或者实现某接口的所有类(扫描文件目录和所有jar)
  18. LeetCode 4 :Majority Element
  19. Hearbeat + Nginx 安装配置
  20. 使用eclipse逆向工程开发hibernate项目

热门文章

  1. js节点操作实例
  2. JavaScript日期格式转换
  3. Redis笔记 -- make编译安装报错记录2则(一)
  4. mybatis中SQL语句运用总结
  5. micro:bit 软件生态系统介绍
  6. 《nginx源代码解析》系列分享专栏
  7. SSM-CRUD入门项目——删除
  8. 20155322 2017-2018-1《信息安全系统设计》第十周 课下作业-IPC
  9. 20155322 《Java程序设计》课堂实践项目 数据库-3-4
  10. [agc001E]BBQ Hard[组合数性质+dp]