装饰器涉及到被装饰函数和装饰函数它自己,被装饰器函数可以参数,那么怎么给装饰器它自己传参数呢。比如游戏中有打和闪现的功能,这时有个装饰器,能给他们都增加一个击退的效果。给装饰器本身的传参作用,在这里就比如,击退的距离,比如打的时候击退两米,闪现的时候击退三米。那么这个参入的参数就可以是这个击退距离。如果不传参的话就需要写两个击退装饰器了。写两个例子演示一下。
演示一:
下面代码演示下说明:
def wrap(x):
def inner(*args,**kwargs):
result = x(*args,**kwargs)
print(x.__name__)
print('这里是击退')
return result
return inner
@wrap #attack = wrap(attack)
def attack(name):
print(f'这里{name}是打,就是这么简单')
return True
attack('lg')
这是装饰器本身参数的版本,@wrap默认自动会把被装饰函数名传给wrap(x)。此外如果需要传入我们自己的一些参数,就需要使用多层嵌套,这里我使用三层嵌套来传参说明,更多层就容易搞乱了:
def wrap_out(n): #这里定义了需要传入一个参数,来表示击退距离
# print(n)
def wrap(x):
def inner(*args,**kwargs):
result = x(*args,**kwargs)
print(x.__name__)
print(f'这里是击退{n}米') #这里得到了参数n的值
return result
return inner
return wrap
@wrap_out(2) #这里给装饰器传入了一个2
def attack(name):
print(f'这里{name}是打,就是这么简单')
return True
attack('lg')
#执行结果
这里lg是打,就是这么简单
attack
这里是击退2米
@wrap_out(2)说明,这里会执行两步:
1:执行wrap_out(2),会得到内层函数wrap的内存地址。
2: 然后执行@wrap,@wrap就相当于执行一个只有传入被装饰器函数名的函数。
如果你想装饰闪现的击退,只需要传入3就可以。
演示2:
给登入界面增加功能,如果会员登入就显示会员看的东西,如果非会员就显示非会员的东西。这里会员和非会员我们当作给装饰器传入的参数,会员和非会员的用户名和密码放在不同的文件中,member和guest中。这只是我想的例子来说明传参装饰器,并不具有实际意义。
def wrap_out(kind):
def wrap(func):
def inner(*args,**kwargs):
username = input("请输入用户名:")
password = input("请输入密码:")
with open(kind,encoding='utf-8') as f1:
for line in f1:
x, y = line.strip().split('|')
if x == username and y == password:
ret = func(*args, **kwargs)
return ret
return
return inner
return wrap
@wrap_out('guest')
def guest():
print("不好意思,这里是游客界面")
@wrap_out('member')
def member():
print("欢迎来到会员界面")
guest()
member()