原文链接:https://www.cnblogs.com/songyunjie/p/16825830.html
这里修正原文代码中的部分错误,调试的python版本为:3.9.16
1、什么是装饰器?
Python的装饰器本质上是一个嵌套函数,它接受被装饰的函数(func)作为参数,并返回一个包装过的函数。这样我们可以在不改变被装饰函数的代码的情况下给被装饰函数或程序添加新的功能。
2、装饰器的基本用法
def func1(func):
def newfunc():
print(1)
func()
print(2)
return newfunc
def func():
print(3)
func = func1(func)
func()
3、@符号用法
def func1(func):
def newfunc():
print(1)
func()
print(2)
return newfunc
@func1
def func():
print(3)
func()
4、装饰器嵌套
def func1(func):
def newfunc():
print(1)
func()
print(2)
return newfunc
def func2(func):
def newfunc1():
print(4)
func()
print(5)
return newfunc1
@func1
@func2
def func():
print(3)
func()
5、用装饰器扩展带有参数的原函数
def func1(func):
def newfunc(who,where):
print('程序开始前')
func(who,where)
print('程序开始后')
return newfunc
@func1
def func(who, where):
print(f"{who}在{where}吃饭")
func('张三','李四家里')
6、用装饰器扩展带有参数和返回值的原函数
def func1(func):
def newfunc(*args, **kwargs):
print(1)
res = func(*args, **kwargs)
print(2)
#print(res)
return res
return newfunc
@func1
def func(*args, **kwargs):
lst = []
dic = {'name':"张三"}
for i in args:
print(i)
for k,v in kwargs.items():
if k in dic:
strvar = dic[k] + 'aaa' + v +'bb'
lst.append(strvar)
return lst
lst = func('电影院',name = '12')
7、类装饰器扩展原函数
class Myclass():
def __call__(self, func):
return self.func2(func)
def func1(func):
def newfunc():
print(1)
func()
print(2)
return newfunc
def func2(self, func):
def newfunc1():
print(3)
func()
print(4)
return newfunc1
# 方法一
@Myclass.func1
def func():
print(5)
func()
# 方法二
@Myclass()
def func():
print(5)
func()
8、带有参数的函数装饰器
def outer(num):
def newfunc(func):
def newfunc1(self):
print(1)
func(self)
print(2)
def newfunc2(self):
print(3)
func(self)
print(4)
if num == 1:
return newfunc1
elif num == 2:
return newfunc2
return newfunc
class Myclass():
@outer(2)
def func1(self):
print(5)
obj = Myclass()
obj.func1()
9、带有参数的类装饰器
class Myclass1():
id = 4445
def __init__(self, num):
self.num = num
def __call__(self, cls):
if self.num == 1:
return self.newfunc1(cls)
else:
return self.newfunc2(cls)
def test(self):
print(1)
def newfunc1(self, cls):
def newfunc():
# 为当前cls这个类添加属性
cls.id = self.id
# 为当前cls这个类添加方法
cls.test = self.test
return cls()
return newfunc
def newfunc2(self, cls):
def newfunc():
# 为当前cls这个类添加属性
cls.id = self.id
# 为当前cls这个类添加方法
cls.test = self.test
if "run" in cls.__dict__:
# print(cls.run(),"123")
# 调用类中方法
res = cls.run(cls)
cls.run = res
return cls()
return newfunc
# 参数1
@Myclass1(1)
class Myclass():
def run(self):
return "亢龙有悔"
obj = Myclass()
print(obj.id)
obj.test()
# @Myclass1()括号中的参数为1时
print(obj.run())
# @Myclass1()括号中的参数非1时
# print(obj.run)