一  装饰器

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 介绍

  • 功能:可以把类中的方法变成属性
  • 作用:控制该属性的 获取, 设置 ,删除 的操作
  1. @property 用来获取值
  2. @自定义名.setter 用来设置值
  3. @自定义名.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)

执行

030. Python装饰器的更多相关文章

  1. 关于python装饰器

    关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...

  2. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  3. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  4. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  5. python 装饰器学习(decorator)

    最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...

  6. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  7. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

  8. Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

  9. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

随机推荐

  1. @babel/preset-env使用polyfill遇到的坑

    场景还原 最近将一个项目由babel@6升级到babel@7,升级后最重要的两个包: @babel/preset-env: 提供代码的转换和API的polyfill的能力 @babel/plugin- ...

  2. GO-05-数据类型

    基本数据类型: 整型.浮点型 float32 float64.复数型(数学中的复数).布尔型.字符串.字符(byte.rune). 复合数据类型: 数组(array).切片(slice).映射(map ...

  3. Ambassador-05-自动重试

    自动重试定义: retry_policy: retry_on: <string> num_retries: <integer> per_try_timeout: <str ...

  4. 手写Spring AOP,快来瞧一瞧看一看撒!

    目录 AOP分析 Advice实现 定义Advice接口 定义前置.后置.环绕和异常增强接口 Pointcut实现 定义PointCut接口 定义正则表达式的实现类:RegExpressionPoin ...

  5. Webpack的理解以及解决了的问题

    一.背景 Webpack 最初的目标是实现前端项目的模块化,旨在更高效地管理和维护项目中的每一个资源 模块化 最早的时候,我们会通过文件划分的形式实现模块化,也就是将每个功能及其相关状态数据各自单独放 ...

  6. Appium 自动化测试框架:关键字驱动+数据驱动

    1. 关键字驱动框架简介 2. 框架结构说明 3. 框架代码实现 action 包  page_action.py business_process 包 case_process.py data_so ...

  7. Jenkins 自定义构建结果

    1. Jenkins 构建原理 2. 脚本执行失败立即停止执行 3. 脚本执行失败继续后面的执行但最终的结果是构建失败 1. Jenkins 构建原理 Jenkins 的构建成功和脚本执行成功是两个事 ...

  8. 1076 Forwards on Weibo

    Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may ...

  9. Python输入与输出

    输出 print函数 语法: print(self, *args, sep=' ', end='\n', file=None) print函数是python中最常见的一个函数.用于将内容打印输出. p ...

  10. SSDT表的遍历

    //VS2005创建的工程,系统xp sp2 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...