今天刚好学到了python的装饰器,写个简短的博客记录下学习心得。
python装饰器从原理上来说,就是python自带的一种扩充函数功能的函数。它可以使得在不改变原有函数的基础上,增添现有函数的功能。
一:使用嵌套函数添加功能:
例如有这样一个函数:
def game():
print("welcome to game area")
你需要为这个函数添加验证的功能,例如,只有登录了,你才能访问游戏专区,我们当然可以直接在函数中添加功能,写成:
def game():
correct_name = "xxx"
correct_psw = "xxx"#假装是数据库取出的
name = input("username:")
psw = input("password:")
if(name == correct_name)and(psw == correct_psw):
print("welcome to game area!")
else:
print("信息错误")
但是这样你修改的原有函数,如果有10个区域需要加入验证呢?你可能给去改变所有的写好的函数吗?这使得出错的可能性大大增加,而且代码也变得冗杂,不符合开放封闭原则。我们可以定义一个嵌套函数,将现有函数传入,仅当符合条件时再来执行。
def login(func):
def inner(*args):
name = "xc"
psw = "123!123"
print("please login")
while True:
name1 = input("name:")
psw1 = input("password:")
if(name1 == name)and(psw1 == psw):
print("-----welcome-----")
func(*args)
break
else:
print("信息错误,请重新输入!")
return inner
这样我们将原有的game函数传入login模块,只有当登录以后才能执行。我们可以将login返回的函数赋值给原有的game函数,这样就实现功能了。但是这也违反了不修改原始函数的原则,那我们应该怎么办呢?装饰器就是为了这样,在不修改原始函数的基础上,去增添函数功能而诞生的。
二:利用装饰器
还是上面的代码,只不过我们不再将返回的inner再赋值给原始的game函数,反而,我们利用装饰器:
@login
def game():
print("welcome to game area")
这起到的效果,与game = login(game)一样的效果,只不过保留了原始的函数,符合开放封闭原则。这个装饰器是如何执行的呢?@login将game函数传入了你之前定义的那个嵌套函数,你执行game,就像在执行已经修饰过的inner这个返回函数。
三:在装饰器中传入参数
那如果,我们要在装饰器中传入参数,该怎么弄呢?可以想到的是,我们需要在嵌套函数中接收装饰器的参数,还是上面的代码,如果我们要在装饰器中传入一个验证方式呢,如下:
def login(log_way = "wx"):
def check_way(func):
def inner(*args):
name = "xc"
psw = "123!123"
print("please login")
while True:
name1 = input("name:")
psw1 = input("password:")
if(name1 == name)and(psw1 == psw):
print("-----welcome-----")
func(*args)
break
else:
print("信息错误,请重新输入!")
return inner
return check_way
就相当于,我们又用了一层函数来接收装饰器的参数,这样可以写成:
@login("phone")
def game():
print("welcome to game area")
原来的装饰器我们可以理解为login(game),这样加入参数后,可以理解为login("phone")(game)。
当然装饰器还有更多的语法与作用,但是我今天就只学到了这里,就先写到这里吧。