Python笔记·第十一章—— 函数 (二) 装饰器

2023-07-10,,

一 为何要用装饰

有的时候写完一段代码,过段时间需要对它进行升级、添加一些新功能,但是如果要直接修改原来的代码会影响其他人的调用,所以就需要一个不修改源代码且不修改原函数的调用方式的东西又能为原函数增添新功能的东西,装饰器就是干这个的。

二 什么是装饰器

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则: 不修改被装饰对象的源代码 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
开放封闭原则:对修改封闭,对扩展开放

三 装饰器的使用

下面是为一个函数添加装饰器,添加了计算其运行时间的功能:

 import time
def timmer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper @timmer
def foo():
time.sleep(3)
print('from foo')
foo()

四、装饰器语法及固定格式

 def 装饰器函数名(func):
def wrapper(*args,**kwargs):
ret = func(*args,**kwargs)
return ret
return wrapper @装饰器函数名
def func():
pass

五、应用练习

 #######################################作业练习#######################################################
#
# 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
# user_exist = [False]
# def auth(func):
# def wrapper(*args,**kwargs):
# #注册功能
# with open('db.txt','r',encoding='utf-8') as f:
# user_dic = eval(f.read())
# flag = False
# while not user_exist[0]:
# username = input('请输入您的用户名:').strip()
# password = input('请输入您的密码:').strip()
# if username in user_dic and password == user_dic[username]:
# print('恭喜您,登录成功!')
# user_exist[0] = True
# break
# else:
# print('账号或密码错误,请重新输入!')
# ret = func(*args,**kwargs)
# return ret
# return wrapper
#
# @auth
# def func1():
# print('函数1')
# @auth
# def func2(x):
# print('函数2',x)
# func1()
# func2(111111)
# 2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
# def log(func):
# def wrapper(*args,**kwargs):
# with open('db2.txt','a',encoding='utf-8') as f:
# f.write('%s函数正在被调用。\n'%func.__name__)
# ret = func(*args,**kwargs)
# return ret
# return wrapper
# @log
# def func1():
# print('func1函数被调用了。。。。')
# @log
# def func2():
# print('func2函数被调用了。。。。')
#
# func1()
# func2()
# 进阶作业(选做):
# 1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
from urllib.request import urlopen # def get_html(url):
# print(urlopen(url).read())
#
# get_html('http://www.baidu.com')
# 2.为题目1编写装饰器,实现缓存网页内容的功能:
# 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
# from urllib.request import urlopen
#
# def get_bak(func):
# def wrapper(*args,**kwargs):
# with open('html.bak','r+',encoding='utf-8') as f:
# if not f.read():
# ret = func(*args, **kwargs)
# print(ret)
# f.write(ret.decode('utf-8'))
# else:
# print('以下内容是从缓存中获得的^^^^^')
# f.seek(0)
# print(f.read())
# ret = func(*args, **kwargs)
# return ret
# return wrapper
#
# @get_bak
# def get_html(url):
# return urlopen(url).read()
# get_html('http://www.python.org')

Python笔记·第十一章—— 函数 (二) 装饰器的相关教程结束。

《Python笔记·第十一章—— 函数 (二) 装饰器.doc》

下载本文的Word格式文档,以方便收藏与打印。