# 有参装饰器
#为什么需要有参装饰器
#前面的学的装饰器的作用是给原函数增加新功能
# 但是当有多个函数需求同样的功能时,又需要一些参数进行区分
# 这时候以前的装饰器就无法解决这个问题了
# 比如下面的例子,想在原函数的基础上加上账号密码判断的功能
# def outter(func):
# def warpper(*args,**kw):
# name = input("input your name>>").strip()
# password = input("input your password>>").strip()
# if name == 'heipi' and password == '123':
# print("基于文件的操作")
# ret = func(*args, **kw)
# return ret
# else :
# print("name or password error")
# return warpper
# @outter
# def index(x,y):
# print("index-->{}:{}".format(x,y))
# index(111,222)
# 添加账号密码验证这个功能基本实现了,但是账号密码有很多种保存方式,比如文件,数据库
# 若账号密码需要从mysql或者mangodb里面拿呢
# 我们需要进一步改进,我们需要判断我们是从哪里拿到数据进行比对
# 所以我们增加一个db_type的变量
# 解决办法一:因为warpper函数的参数不能变
# 所以我们在outter函数中添加一个变量db_type
# def outter(func, db_type):
# def warpper(*args,**kw):
# name = input("input your name>>").strip()
# password = input("input your password>>").strip()
# if db_type == 'file':
# if name == 'heipi' and password == '123':
# print("基于文件的操作")
# ret = func(*args, **kw)
# return ret
# else :
# print("name or password error")
# elif db_type == 'mysql':
# # 为了逻辑更加的清晰,账号密码验证就不写了
# print("基于Mysql的操作")
# elif db_type == 'Mongodb':
# print("基于Mongodb的操作")
# return warpper
# # 因为语法糖的效果是将@装饰器下面的函数名作为参数传递给装饰器然后返回给自己
# # 即@outter ---> index = outter(index)
# # 所以我们这里不能使用语法糖了,只能自己手动调用
# def index(x,y):
# print("index --->{}:{}".format(x,y))
# def baseMysql(x,y):
# print("baseMysql")
# def baseMongo(x,y):
# print("baseMongodb")
# index = outter(index,'file')
# baseMysql = outter(baseMysql,'mysql')
# baseMongo = outter(baseMongo,"Mongodb")
# index(111,222)
# baseMysql(111,222)
# baseMongo(111,222)
# 到这里也算是实现了这个基本功能,但是不能使用语法糖,比较lower
# 我们再来优化,还是传参有两种方式:直接传参与闭包
# 这里直接传参会导致无法使用语法糖,所以改用闭包
# def deco(db_type):
# # db_type = 'file'
# def outter(func):
# def warpper(*args,**kw):
# name = input("input your name>>").strip()
# password = input("input your password>>").strip()
# if db_type == 'file':
# if name == 'heipi' and password == '123':
# print("基于文件的操作")
# ret = func(*args, **kw)
# return ret
# else :
# print("name or password error")
# elif db_type == 'mysql':
# # 为了逻辑更加的清晰,账号密码验证就不写了
# print("基于Mysql的操作")
# elif db_type == 'Mongodb':
# print("基于Mongodb的操作")
# return warpper
# return outter
# # 这里调用deco返回outter,再去调用@outter ,下面的同理
# outter = deco('file')
# @outter
# def index(x,y):
# print("index --->{}:{}".format(x,y))
# outter = deco('mysql')
# @outter
# def baseMysql(x,y):
# print("baseMysql")
# outter = deco('Mongodb')
# @outter
# def baseMongo(x,y):
# print("baseMongodb")
# index(111,222)
# baseMysql(111,222)
# baseMongo(111,222)
# 基本功能已经实现,还可以继续优化一下
# 可以将
# outter = deco('Mongodb')
# @outter
# 改写为@deco(db_type)
def deco(db_type):
# db_type = 'file'
def outter(func):
def warpper(*args,**kw):
name = input("input your name>>").strip()
password = input("input your password>>").strip()
if db_type == 'file':
if name == 'heipi' and password == '123':
print("基于文件的操作")
ret = func(*args, **kw)
return ret
else :
print("name or password error")
elif db_type == 'mysql':
# 为了逻辑更加的清晰,账号密码验证就不写了
print("基于Mysql的操作")
elif db_type == 'Mongodb':
print("基于Mongodb的操作")
return warpper
return outter
# 这里调用deco返回outter,再去调用@outter ,下面的同理
@deco('file')
def index(x,y):
print("index --->{}:{}".format(x,y))
@deco('mysql')
def baseMysql(x,y):
print("baseMysql")
@deco('Mongodb')
def baseMongo(x,y):
print("baseMongodb")
index(111,222)
baseMysql(111,222)
baseMongo(111,222)
# 我们可以看到@deco(db_type),这个装饰器
# 他的执行步骤是
# 1.outter = deco(db_type)
# 2.@outter
总结:所有的有参装饰器,最多只用包围三层,因为最外层的deco的参数不受限制
这里是无参装饰器的详解:无参装饰器