装饰器
def outer(func): def inner(): print('before') func() print('after') return inner @outer def f1(): print('f1')
功能:
1.自动执行outer()函数,并把outer函数下面的函数名作为参数传递给outer函数
2.将outer函数的返回值重新赋值给f1
以上代码执行过后:
1.f1不在指向原来的f1函数,而是执行inner函数
2.func执指向原来的f1函数
也就是说函数被装饰器装饰之后,被装饰的函数名引用指向装饰器函数的内层函数即inner()
- 一.装饰器流程之返回值
def outer(func): def inner(): print('before') ret = func() # 接收原来f1函数的返回值 print('after') return ret # 将函数之返回 return inner @outer def f1(): return 'f1' f1()
- 二.装饰器流程之参数
def outer(func): def inner(a,b): # 加参数 print('before') ret = func(a,b) # 加参数 print('after') return ret # 将函数之返回 return inner @outer def f1(a, b): return a + b f1(1,2)
- 三.装饰器流程之多参数
def outer(func): def inner(*args,**kwargs): # 加参数 print('before') ret = func(*args,**kwargs) # 加参数 print('after') return ret # 将函数之返回 return inner @outer def f1(a, b): return a + b f1(1,2)
- 装饰器带参数
""" 装饰器不带参数时,直接返回的是一个函数 inner 装饰器带参数之后,第一个外层函数接收参数,并返回一个装饰器 outer """ def outer_args(args): # args 接收装饰器的参数 def outer(func): # func 接收需要装饰的函数 # 扩展函数功能 def inner_admin_user(): print('before', 'admin') result = func() print('after', 'admin') return result # 扩展函数功能 def inner_commons_user(): print('before', 'commons') result = func() print('after', 'commons') return result # 根据装饰器的参数返回不同的装饰之后的函数 if args == 'admin': return inner_admin_user else: return inner_commons_user # 返回装饰器 return outer @outer_args('admin') def f1(): print('F1') return 'f1' ret = f1() print(ret) @outer_args('select') def f2(): print('F2') return 'f2' res = f2() print(res)
- 使用类做装饰器
""" 使用类作为装饰器: 1. 需要定义__call__(self, func) 用以接收被装饰的函数名参数 2. 在类中在定义一个方法,扩展功能 3. self.func = func 把被装饰的函数名封装到对象中 4. return self.inner 把返回的函数封装到对象中 5. 如果装饰器需要传入参数,类中需定义__init__(self, args) 用以接收参数 6. 使用类中装饰器是 @Decorator1() 有个括号 """ class Decorator1(object): # 使用类作为装饰器 且装饰器不带参数 # 一个用于接收基本函数装饰器 def __call__(self, func): print(func) self.func = func # 把被装饰的函数名封装到对象中 return self.inner # 把返回的函数封装到对象中 # 一个用于扩展功能 def inner(self): print('before') ret = self.func() print('after') return ret class Decorator2(object): # 装饰器带参数 def __init__(self, args): self.args = args def __call__(self, func): self.func = func if self.args == 'admin': return self.inner_admin_user else: return self.inner_commons_user def inner_admin_user(self): print('before', 'admin') result = self.func() print('after', 'admin') return result def inner_commons_user(self): print('before', 'commons') result = self.func() print('after', 'commons') return result @ Decorator1() def f1(): print('f1') f1() @Decorator2('admin') def f2(): print('f1') f2() @Decorator2('commons') def f2(): print('f1') f2()
- 为类添加装饰器
""" 为类添加装饰器: 1. outer(cls) cls为类名 2. 内层函数需返回对象 3.为类加装饰器用处在什么地方呢,参数为cls 除了创建对象, 调用类中的方法,还有什么呢 """ def decorator(args): def outer(cls): def inner_morning(): print('早上开始创建对象..') obj = cls() print('始创建对象结束..') return obj # 需返回对象 def inner_noon(): print('中午开始创建对象..') obj = cls() print('始创建对象结束..') return obj if args == '12': return inner_morning else: return inner_noon return outer @decorator('13') class Work(object): pass aa = Work()
- 四.装饰器流程练习
UserInfo = {'name': 'alex', 'age': 18, 'sex': '男'}
Login_flag = False
Login_type = None
# 用户登陆查询用户信息,查看信息之前先登陆,进行后台管理,必须是管理员
def check_login(func):
def inner(*args,**kwargs):
if Login_flag is True:
func()
else:
print('请先登陆...')
return inner
def check_type(func):
def inner(*args,**kwargs):
if Login_type == 1:
func()
else:
print('无权限')
return inner
def login(name, pwd):
global Login_flag, Login_type
if name == 'admin':
Login_flag = True
Login_type = 1
elif name == 'alex' and pwd == '123':
Login_flag = True
else:
pass
@check_login
def select():
for li in UserInfo.keys():
print(UserInfo[li])
@check_login
@check_type
def admin():
print('后台管理')
inp = input('1:登陆 2:查看用户,3:后台管理\n>>>')
name = input('UserName:>>>')
pwd = input('PassWord:>>>')
if inp == '1':
login(name, pwd)
elif inp == '2':
select()
elif inp == '3':
# login(name, pwd)
login(name, pwd)
admin()