上次总结到,当定义的函数含有参数的情况,装饰器该如何实现。本次继续总结多参数情况,以及类装饰器相关内容。
# 装饰带有多参数的函数
# 需要注意函数的参数类型
def outer(func):
def inner(who,name,*args,**kwargs):
print(‘约朋友周末逛街。。。‘)
func(who,name,*args,**kwargs)
print(‘天黑了,各回各家!‘)
return inner
# 定义多参数的 函数
@outer
def func(who,name,*args,**kwargs):
print(f‘{who}跟{name}先去逛街。。。‘)
print(‘然后吃了小吃‘,args)
print(‘看了一场电影‘,kwargs)
func(‘张三‘,‘李四‘,‘热干面‘,‘臭豆腐‘,‘奶茶‘,mov=‘夺冠‘)
‘‘‘
约朋友周末逛街。。。
张三跟李四先去逛街。。。
然后吃了小吃 (‘热干面‘, ‘臭豆腐‘, ‘奶茶‘)
看了一场电影 夺冠
天黑了,各回各家!
‘‘‘
在查看代码时有可能会遇到带有参数的装饰器,例如Django框架中的 @login_required(login_url=‘/accounts/login/‘)
# 如果你的装饰器需要有参数,那么给当前的装饰器套一个壳,用于接收装饰器的参数
def kuozhan(var):
def outer(func):
def inner1():
print(‘11111‘)
func()
def inner2():
print(‘222222‘)
func()
# 装饰器壳的参数,可以用于在函数内去做流程控制
if var == 1:
return inner1
else:
return inner2
return outer
@kuozhan(2) # kuozhan(var) ==> outer() ==> outer(func) ==> inner()
def func():
print(‘我是一个函数‘)
func()
‘‘‘
222222
我是一个函数
‘‘‘
# 类装饰器装饰函数
class Outer():
# 魔术方法:当把该类的对象当作函数调用时,自动触发 obj()
def __call__(self,func):
self.func = func # 把传进来的函数作为对象的成员方法
return self.inner # 返回一个函数
# 在定义的需要返回的新方法中 去进行装饰和处理
def inner(self,who):
print(‘打开冰箱门。。。‘)
self.func(who)
print(‘关闭冰箱门。。。‘)
@Outer() # Outer() ==> obj @obj==>obj(func) ==> __call__(func) ==> inner()
def func(animal):
print(f‘{animal}放进冰箱。。。‘)
func(‘大象‘) # inner(‘大象‘)
‘‘‘
打开冰箱门。。。
大象放进冰箱。。。
关闭冰箱门。。。
‘‘‘
以上所以形式的装饰器,包括 函数装饰器,类装饰器等,都有一个共同特点:都是在给函数去进行装饰,增加功能。
还有一种装饰器,是专门装饰类的。也就是在类的定义的前面使用@装饰器这种语法
装饰器给函数进行装饰,目的是不改变函数调用和代码的情况下给原函数增加了新的功能。
装饰器给类进行装饰,目的是不改变类的定义和调用的情况下给类增加新的成员(属性或方法)。
# 使用函数装饰器,给类进行装饰,增加新的属性和方法
# 定义函数,接收一个类。返回修改后的类
def kuozhan(cls):
def func2():
print(‘我是在装饰器中追加的新方法,func2‘)
cls.func2 = func2 # 把刚才定义的方法赋值给 类
cls.name = ‘我是在装饰器中追加的新属性 name‘
#返回时,把追加类新成员的 类 返回去
return cls
@kuozhan # kuozhan(Demo) ==> cls ==> Demo
class Demo():
def func():
print(‘我是Demo类中定义的func方法‘)
Demo.func() # 我是Demo类中定义的func方法
Demo.func2() # 我是在装饰器中追加的新方法,func2
print(Demo.name) # 我是在装饰器中追加的新属性 name
装饰器(2)归纳完毕,下周总结MySQL数据库相关内容,下周见~
原文:https://www.cnblogs.com/yzq2333/p/13814584.html