装饰器的作用:在不改变原对象的情况下给原对象增加功能
装饰器由闭包和语法糖组成。装饰器一般可以由函数、类来实现。因为类和函数都是callable的,都可以使用括号来调用运行他。
class A:
def __call__(self):
print('a')
a = A()
a()
装饰器本身需要接受一个被装饰的对象作为参数,该参数通常为函数、方法、类等对象。
装饰器需要返回一个对象,该对象可以是 经过处理的原参数对象、一个包装且类似原参数
的对象;或者返回一个不相干内容
有对装饰器不太理解的同学可以参照这我下面的代码案例进行理解,相信看完你就对装饰器有一个新的认识!
@函数名 是python的一种语法糖。
def check_access(sg):
def check():
name = input("输入用户名")
if name == "zzy":
sg()
else:
print("无权查看")
return check
@check_access
def select_goods():
print("开始查询商品")
select_goods()
解析内部执行的逻辑:
def select_goods():
print('开始查找')
def decorator(func):
if input("请输入用户名:") == 'zzy':
func()
else:
print("无权查看")
#原来的调用方法
#select_goods()
#这样虽然可以不改变原来方法的情况下增加功能,但是调用形式和之前差别很大。
decorator(select_goods)
#依然使用select_goods方法调用该怎么做?
#将select_goods指向一个新的函数,拥有decorator的功能,
#此时要借助闭包了。
def decorator2(func):
def new_func():
if input("请输入用户名:") == 'zzy':
func()
else:
print("无权查看")
return new_func
select_goods =decorator2(select_goods)
select_goods()
多个装饰器的顺序:
def decorator1(func):
def decorator_func():
print('decorator1 begin')
func()
print('decorator1 end')
return decorator_func
def decorator2(func):
def decorator_func():
print('decorator2 begin')
func()
print('decorator2 end')
return decorator_func
@decorator1
@decorator2
def my_func():
print("my_func")
my_func()
装饰类内部的实例方法:
def decorator(func):
def decorator_func(self):#内部函数的参数和返回值要和被装饰的函数保持一致
print('before')
func(self)
print('after')
return decorator_func
class TestClass:
@decorator
def func(self):
print('func')
t = TestClass()
t.func()
给装饰器传参数:
def outer(a):
def decorator1(func):
def decorator_func():
nonlocal a
print(a)
print('decorator1 begin')
func()
print('decorator1 end')
return decorator_func
return decorator1
@outer(123)#相当于调用了outer(),获得decorator1,继续装饰my_func
def my_func():
print("my_func")
my_func()
装饰类内部的类方法和静态方法:
def decorator(func):
def decorator_func(self):#内部函数的参数和返回值要和被装饰的函数保持一致
print('before')
func(self)
print('after')
return decorator_func
def decorator2(func):
def decorator_func():#内部函数的参数和返回值要和被装饰的函数保持一致
print('before')
func()
print('after')
return decorator_func
def decorator3(func):
def decorator_func(cls):#内部函数的参数和返回值要和被装饰的函数保持一致
print('before')
func(cls)
print('after')
return decorator_func
class TestClass:
@decorator
def func(self):
print('func')
@classmethod
@decorator3
def class_func(cls):
print(cls.__mro__)
@staticmethod
@decorator2
def static_func():
print('static_func')
t = TestClass()
TestClass.static_func()
TestClass.class_func()
使用写在类中的装饰函数:
class Decorator:
def dec1(self,func): #注意使用装饰的时候是 对象.dec4,注意与第四个的区别
def dec_func(self1):
print('before')
func(self1)
print('end')
return dec_func
@staticmethod
def dec2(func):
def dec_func(self):
print('before')
func(self)
print('end')
return dec_func
@classmethod
def dec3(cls,func):
def dec_func(self):
print('before')
func(self)
print('end')
return dec_func
def dec4(func): #注意使用装饰的时候是 类名.dec4,注意与第一个的区别
def dec_func(self):
print('before')
print(func)
print('end')
return dec_func
decorator = Decorator()
class A:
@decorator.dec1
def f1(self):
print('f1')
@Decorator.dec2
def f2(self):
print('f2')
@Decorator.dec3
def f3(self):
print('f3')
@Decorator.dec4
def f4(self):
print('f4')
a = A()
a.f1()
a.f2()
a.f3()
a.f4()