一  装饰器

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. .NET Request对象介绍

    Request对象用于检索从浏览器向服务器所发送的请求信息.它提供对当前页请求的访问,包括标题,Cookie,客户端证书等等.它也与HTTP协议的请求消息对应 Request常用的属性 属性 具体内容 ...

  2. (九)Struts2模型驱动和属性驱动

    出于结构清晰的考虑,应该采用单独的Model实例来封装请求参数和处理结果,这就是所谓的模型驱动, 所谓模型驱动,就是使用单独的JavaBean来贯穿整个MVC流程. 所谓属性驱动,就是使用属性来作为贯 ...

  3. 编程相关术语(Python)

    1. 程序的组成 程序 (program):(1)由一系列定义计算机如何执行计算的指令组成.(本质) (2)程序(算法)由对象.表达式和语句组成.(元素) 1.1程序的指令类型 输入 (input): ...

  4. Windows搭建Linux子系统(WSL)详细教程

    介绍 WSL(windows下的Linux子系统) Windows Subsystem for Linux(简称WSL)是一个在Windows 10上能够运行原生Linux二进制可执行文件(ELF格式 ...

  5. 数据结构☞二叉搜索树BST

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...

  6. Day01_06_Java注释

    Java注释 注释 - 单行注释:// xxxxx - 多行注释:/* xxxxx */ - javadoc注释: /** * * * */ - javadoc注释可以被bin目录下的javadoc. ...

  7. 【Navicat】获取表结构的DDL语句以及获取更新表字段的操作的DDL

    1.获取表结构的DDL语句 2.获取修改表结构某一字段的DDL语句  设计表-修改表字段(记住不要保存)-SQL预览

  8. 【接口设计】用户积分排行榜功能-Redis实现

    一.排行榜功能简介 排行榜功能是一个很普遍的需求.使用 Redis 中有序集合(SortedSet)的特性来实现排行榜是又好又快的选择. 一般排行榜都是有实效性的,比如交通数据流中的路口/路段的车流量 ...

  9. sublime text 快捷键的使用大全

    多行选择后按下ctrl+/ 选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑.举个栗子:快速选中 ...

  10. 认识二进制安全与漏洞攻防技术 (Windows平台)

    二进制漏洞是指程序存在安全缺陷,导致攻击者恶意构造的数据(如Shellcode)进入程序相关处理代码时,改变程序原定的执行流程,从而实现破坏或获取超出原有的权限. 0Day漏洞 在计算机领域中,0da ...