一 装饰器
1.1 装饰器介绍
扩展函数新功能的@
定义:替换旧函数,返回新函数,在不改变原有代码的前提下,为该函数扩展新功能;
语法:@ (语法糖)
1.2 装饰器的原型
def show(func): def showtime(): print ("演出开始") func() print ("演出结束") return showtime def func(): print ("正在演出") res = show(func) res()
执行
[root@node10 python]# python3 test.py 演出开始 正在演出 演出结束
res换成func
def show(func): def showtime(): print ("演出开始") func() print ("演出结束") return showtime def func(): print ("正在演出") func = show(func) # func = showtime <==> func() 就是showtime() 一样的 func()
print(func)
执行
[root@node10 python]# python3 test.py 演出开始 正在演出 演出结束
<function show.<locals>.showtime at 0x7f3bc56a0158>
1.3 装饰器语法@
def show(func): def showtime(): print ("演出开始") func() print ("演出结束") return showtime @show #func = show(func) def func(): print ("正在演出") func()
执行
[root@node10 python]# python3 test.py 演出开始 正在演出 演出结束
方向:从下到上,把func当成一个参数给装饰器showt,返回的新函数覆盖旧函数func,func在调用时,相当于调用showtime(),只不过@自动帮助你实现了这一步,func = show(func)直接调用即可.
1.4 装饰器的嵌套
def show1(func): def showtime(): print ("演出开始") func() print ("演出结束") return showtime def show2(func): def showtime(): print ("准备演出") func() print ("退出演出") return showtime @show1 @show2 def func(): print ("正在演出") func()
执行
演出开始 准备演出 正在演出 退出演出 演出结束
执行过程
1 自下而上执行,先执行@show2,即达到func = showtime(func),即此时func是
print ("准备演出") print ("正在演出") print ("退出演出")
2 在执行@show1,此时在执行show1的func = showtime(func)即此时func是
print ("演出开始") print ("准备演出") print ("正在演出") print ("退出演出") print ("演出结束")
3 得到最终结果
[root@node10 python]# python3 test.py 演出开始 准备演出 正在演出 退出演出 演出结束
1.5 带有参数的装饰器
如果原函数带有参数, 那么返回的新函数也要带有参数,(参数一一对应)
def show(func): def showtime(who,where): print ("准备演出") func(who,where) print ("退出演出") return showtime @show def func(who,where): print ("{}正在{}演出".format(who,where)) func("张靓颖","鸟巢")
执行
[root@node10 python]# python3 test.py 准备演出 张靓颖正在鸟巢演出 退出演出
1.6 带有参数返回值的装饰器
元祖和字典的参数用法,* 和 ** 的魔术用法 *[1,2,3] **{'a':1,'b':2} 把容器里面的数据,一个一个拿出来当成参数赋给调用处的func
def func(*args): print(args) func(1,2,3,4,5)
执行
[root@node10 python]# python3 test.py (1, 2, 3, 4, 5)
字典
def func(*args,**kwargs): print(args) print(kwargs) func(1,2,3,4,5,a = 5,b = 6)
执行
[root@node10 python]# python3 test.py (1, 2, 3, 4, 5) {'a': 5, 'b': 6}
实例
#带有参数的装饰器 def func_arg(arg): def funcAll(funcName): def func_in(*args,**kwargs): if arg=="2":#根据装饰的参数不同,可以进行不同的处理 ret=funcName(*args,**kwargs) ret=funcName(*args,**kwargs) else: ret=funcName(*args,**kwargs) print("arg is %s"%arg) return ret return func_in return funcAll #运行分析: #1 先执行func_arg("hello")函数,这个函数return的结果是func这个函数的引用 #2 @func_arg("hello")----->@funcAll #3 使用@func对testArg()进行装饰 @func_arg("hello") def testArg(): print("---带有参数的装饰器---") @func_arg("2") def testArg2(): print("---带有参数的装饰器---") testArg() testArg2()
执行
[root@node10 python]# python3 test.py ---带有参数的装饰器--- arg is hello ---带有参数的装饰器--- ---带有参数的装饰器--- arg is 2
def func(*args,**kwargs): dictvar = {"xunyu":"荀彧","zhugeliang":"诸葛亮","zhangzhao":"张昭"} lst = {a:b for a,b in kwargs.items() if a in dictvar} return lst res = func("魏蜀吴","三国",xunyu="曹操",zhugeliang="刘备",zhangzhao="孙权") print (res)
执行
[root@node10 python]# python3 test.py {'xunyu': '曹操', 'zhugeliang': '刘备', 'zhangzhao': '孙权'}
替换
def func(*args,**kwargs): dictvar = {"xunyu":"荀彧","zhugeliang":"诸葛亮","zhangzhao":"张昭"} lst = {dictvar[a]:b for a,b in kwargs.items() if a in dictvar} return lst res = func("魏蜀吴","三国",xunyu="曹操",zhugeliang="刘备",zhangzhao="孙权") print (res)
执行
[root@node10 python]# python3 test.py {'荀彧': '曹操', '诸葛亮': '刘备', '张昭': '孙权'}
使用字符串
def func(*args,**kwargs): dictvar = {"xunyu":"荀彧","zhugeliang":"诸葛亮","zhangzhao":"张昭"} #lst = {dictvar[a]:b for a,b in kwargs.items() if a in dictvar} lst = [dictvar[a]+"主公是"+b for a,b in kwargs.items() if a in dictvar] return lst res = func("魏蜀吴","三国",xunyu="曹操",zhugeliang="刘备",zhangzhao="孙权") print (res)
执行
[root@node10 python]# python3 test.py ['荀彧主公是曹操', '诸葛亮主公是刘备', '张昭主公是孙权']
1.7 装饰器进行扩展
def chuzheng(func):
# 函数的定义处,*args,**kwargs 是收集参数 def chuzhengtime(*args,**kwargs): print ("出谋划策") lst = func(*args,**kwargs) print ("烽火连天") return lst return chuzhengtime def func(*args,**kwargs): print (args) dictvar = {"xunyu":"荀彧","zhugeliang":"诸葛亮","zhangzhao":"张昭"} #lst = {dictvar[a]:b for a,b in kwargs.items() if a in dictvar} lst = [dictvar[a]+"主公是"+b for a,b in kwargs.items() if a in dictvar] return lst res = func("魏蜀吴","三国",xunyu="曹操",zhugeliang="刘备",zhangzhao="孙权") print (res)
执行
[root@node10 python]# python3 test.py ('魏蜀吴', '三国') ['荀彧主公是曹操', '诸葛亮主公是刘备', '张昭主公是孙权']
使用装饰器
def chuzheng(func): def chuzhengtime(*args,**kwargs): print ("出谋划策") lst = func(*args,**kwargs) print ("烽火连天") return lst return chuzhengtime @chuzheng def func(*args,**kwargs): print (args) dictvar = {"xunyu":"荀彧","zhugeliang":"诸葛亮","zhangzhao":"张昭"} #lst = {dictvar[a]:b for a,b in kwargs.items() if a in dictvar} lst = [dictvar[a]+"主公是"+b for a,b in kwargs.items() if a in dictvar] return lst res = func("魏蜀吴","三国",xunyu="曹操",zhugeliang="刘备",zhangzhao="孙权") print (res)
执行
[root@node10 python]# python3 test.py 出谋划策 ('魏蜀吴', '三国') 烽火连天 ['荀彧主公是曹操', '诸葛亮主公是刘备', '张昭主公是孙权']
二 property 装饰器
2.1 介绍
- 功能:可以把类中的方法变成属性
- 作用:控制该属性的 获取, 设置 ,删除 的操作
- @property 用来获取值
- @自定义名.setter 用来设置值
- @自定义名.deleter 用来删除值
class MyClass(): def __init__(self,name): self.name = name def username(self): return self.name obj = MyClass("John") res = obj.username() print (res)
执行
[root@node10 python]# python3 test.py John
2.2 使用property
class MyClass(): def __init__(self,name): self.name = name @property def username(self): return self.name obj = MyClass("John")
#获取username属性 print (obj.username)
执行
[root@node10 python]# python3 test.py John
2.3 设置和删除
class MyClass(): def __init__(self,name): self.name = name @property def username(self): return self.name @username.setter def username(self,val): self.name = val @username.deleter def username(self): del self.name obj = MyClass("John") print (obj.username) #设置username属性 obj.username = "wellian" print(obj.username) #删除username属性 del obj.username #这个可以删除,但是不能执行打印,会报错 #print(obj.username)
执行
[root@node10 python]# python3 test.py John wellian
打印删除的属性
class MyClass(): def __init__(self,name): self.name = name @property def username(self): return self.name @username.setter def username(self,val): self.name = val @username.deleter def username(self): del self.name obj = MyClass("John") print (obj.username) #设置username属性 obj.username = "wellian" print(obj.username) #删除username属性 del obj.username print(obj.username)
执行
2.4 控制
可以使用pass占位,则就取不到username的值
class MyClass(): def __init__(self,name): self.name = name @property def username(self): #return self.name pass @username.setter def username(self,val): self.name = val @username.deleter def username(self): del self.name obj = MyClass("John") print (obj.username) #设置username属性 #obj.username = "wellian" #print(obj.username) #删除username属性 #del obj.username #print(obj.username)
执行,就取不到值
设置使用控制
class MyClass(): def __init__(self,name): self.name = name @property def username(self): return self.name #pass @username.setter def username(self,val): #self.name = val pass @username.deleter def username(self): del self.name obj = MyClass("John") #print (obj.username) #设置username属性 obj.username = "wellian" print(obj.username) #删除username属性 #del obj.username #print(obj.username)
执行,发现设置并没有成功
同样删除也进行控制
class MyClass(): def __init__(self,name): self.name = name @property def username(self): return self.name #pass @username.setter def username(self,val): #self.name = val pass @username.deleter def username(self): #del self.name pass obj = MyClass("John") #print (obj.username) #设置username属性 #obj.username = "wellian" #print(obj.username) #删除username属性 del obj.username print(obj.username)
执行,仍然有值
2.5 第二种写法
class MyClass(): def __init__(self,name): self.name = name def getusername(self): return self.name #pass def setusername(self,val): self.name = val #pass def delusername(self): del self.name #pass
#按照顺序传参,获取,设置, 删除
username = property(getusername,setusername,delusername) obj = MyClass("John") print (obj.username) #设置username属性 obj.username = "wellian" print(obj.username) #删除username属性 del obj.username print(obj.username)
执行
推荐使用,当在定义一个可以直接定义
class MyClass(): def __init__(self,name): self.name = name def getusername(self): return self.name #pass def setusername(self,val): self.name = val #pass def delusername(self): del self.name #pass username = property(getusername,setusername,delusername) address = property(getusername,setusername,delusername) obj = MyClass("John") print (obj.username) #设置username属性 #obj.username = "wellian" #print(obj.username) #删除username属性 #del obj.username #print(obj.username) print (obj.address)
执行