Python基础(三)装饰器
装饰器:在代码运行期间动态增加功能的方式,称之为装饰器(Decorator)。本质就是函数,功能是为其他函数添加附加功能,原则:不修改被修饰函数的源代码,不修改被修饰函数的调用方式装饰器 = 高阶函数 + 函数嵌套 + 闭包高阶函数函数的传入参数是一个函数名函数的返回值是一个函数名满足上述条件任意一个即为高阶函数1.传入参数是一个函数名:可以实现在不修改源代...
·
装饰器:在代码运行期间动态增加功能的方式,称之为装饰器(Decorator)
。本质就是函数,功能是为其他函数添加附加功能,
原则:不修改被修饰函数的源代码,不修改被修饰函数的调用方式
装饰器 = 高阶函数 + 函数嵌套 + 闭包
高阶函数
- 函数的传入参数是一个函数名
- 函数的返回值是一个函数名
- 满足上述条件任意一个即为高阶函数
1.传入参数是一个函数名:
可以实现在不修改源代码的情况下为函数添加功能,但是修改了函数的调用方式
def foo():
print('hello')
def test(func): #高阶函数,传入参数是一个函数名
print(func) #打印foo的内存地址 <function foo at 0x00000000005C3E18>
func() #执行foo函数 hello
test(foo)
import time
def foo():
time.sleep(1)
print('hello')
def test(func):
start_time=time.time()
func()
stop_time=time.time()
print('函数运行时间 %s' %(stop_time - start_time))
test(foo)
# 运行结果
hello
函数运行时间 1.0000572204589844
2.返回值是一个函数名:
可以实现装饰器不修改函数调用方式的功能
def foo():
print('hello')
def test(func):
return func
foo = test(foo)
foo()
import time
def foo():
time.sleep(1)
print('hello')
#不修改foo函数源代码,不修改foo调用方式
def timer(func):
start_time=time.time()
func()
stop_time=time.time()
print('函数运行时间 %s' %(stop_time - start_time))
return func
foo = timer(foo)
foo()
# 运行结果
hello
函数运行时间 1.0000572204589844
hello #会多运行一步
函数嵌套:函数里边定义函数
def foo(name):
def test(): #函数即变量
print(name)
#print(locals()) ##打印当前局部变量(2个) {'test': <function foo.<locals>.test at 0x00000000028A1A60>, 'name': 'hehe'}
test()
foo('hehe') #hehe
闭包:函数作用域的一种体现
装饰器基本实现:
import time
def timmer(func): #func=test
def wrapper():
start_time = time.time()
func() #就是运行test()
stop_time = time.time()
print('函数运行时间%s' %(stop_time-start_time))
return wrapper
@timmer #相当于 test = timmer(test)
def test():
time.sleep(1)
print('test函数运行完毕')
# res = timmer(test) #返回的是wrapper的内存地址
# res() #执行的是wrapper()
#test = timmer(test)
test()
装饰器获取原函数返回值
:
import time
def timmer(func):
def wrapper():
start_time = time.time()
res = func()
stop_time = time.time()
print('函数运行时间%s' %(stop_time-start_time))
return res
return wrapper
@timmer
def test():
time.sleep(1)
print('test函数运行完毕')
return '这是test函数的返回值'
res = test() #就是在运行wrapper
print(res)
加参数:
def timmer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
stop_time = time.time()
print('函数运行时间%s' %(stop_time-start_time))
return res
return wrapper
@timmer
def test(name,age):
time.sleep(1)
print('name is %s,age is %s' %(name,age))
return '这是test函数的返回值'
test('user',18)
练习1:使用装饰器为函数加上认证功能
user_list = [
{'name':'user1','password':'pwd1'},
{'name':'user2','password':'pwd2'},
{'name':'user3','password':'pwd3'},
{'name':'user4','password':'pwd4'}
]
current = {'username':None,'login':False} #用于判断登录状态信息,避免每个函数都要进行验证的问题
def auth_func(func):
def wrapper(*args,**kwargs):
if current['username'] and current['login']: #如果是登录状态,直接运行函数
res = func(*args,**kwargs)
return res
username = input('用户名:').strip()
password = input('密码:').strip()
for user in user_list:
if username == user['name'] and password == user['password']:
current['username'] = username #认证完成后,修改状态信息
current['login'] = True
res = func(*args, **kwargs)
return res
else:
print('用户名或者密码错误')
return wrapper
@auth_func
def index():
print('welcome')
@auth_func
def home(name):
print('%s 的个人主页' %name)
index()
home('user1')
练习2:带参数装饰器
user_list = [
{'name':'user1','password':'pwd1'},
{'name':'user2','password':'pwd2'},
{'name':'user3','password':'pwd3'},
{'name':'user4','password':'pwd4'}
]
current = {'username':None,'login':False}
def auth(auth_type='filedb'):
def auth_func(func):
def wrapper(*args,**kwargs):
print('认证方式是---->%s' %auth_type)
if auth_type == 'filedb':
if current['username'] and current['login']:
res = func(*args,**kwargs)
return res
username = input('用户名:').strip()
password = input('密码:').strip()
for user in user_list:
if username == user['name'] and password == user['password']:
current['username'] = username
current['login'] = True
res = func(*args, **kwargs)
return res
else:
print('用户名或者密码错误')
elif auth_type == 'ldap':
res = func(*args, **kwargs)
return res
return wrapper
return auth_func
@auth(auth_type='filedb')
def index():
print('welcome')
@auth(auth_type='ldap')
def home(name):
print('%s 的个人主页' %name)
index()
home('user1')
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)