学习python装饰器_Python装饰器学习(九步入门)
这是在Python学习小组上介绍的内容,现学现卖、多练习是好的学习方式。
第一步:最简单的函数,准备附加额外功能
# -*- coding:gbk -*-
'''示例1: 最简单的函数,表示调用了两次'''
def myfunc():
print("myfunc() called.")
myfunc()
myfunc()
第二步:使用装饰函数在函数执行前和执行后分别附加额外功能
# -*- coding:gbk -*-
'''示例2: 替换函数(装饰)
装饰函数的参数是被装饰的函数对象,返回原函数对象
装饰的实质语句: myfunc = deco(myfunc)'''
def deco(func):
print("before myfunc() called.")
func()
print(" after myfunc() called.")
return func
def myfunc():
print(" myfunc() called.")
myfunc = deco(myfunc)
myfunc()
myfunc()
第三步:使用语法糖@来装饰函数
# -*- coding:gbk -*-
'''示例3: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
但发现新函数只在第一次被调用,且原函数多调用了一次'''
def deco(func):
print("before myfunc() called.")
func()
print(" after myfunc() called.")
return func
@deco
def myfunc():
print(" myfunc() called.")
myfunc()
myfunc()
第四步:使用内嵌包装函数来确保每次新函数都被调用
# -*- coding:gbk -*-
'''示例4: 使用内嵌包装函数来确保每次新函数都被调用,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
def deco(func):
def _deco():
print("before myfunc() called.")
func()
print(" after myfunc() called.")
# 不需要返回func,实际上应返回原函数的返回值
return _deco
@deco
def myfunc():
print(" myfunc() called.")
return 'ok'
myfunc()
myfunc()
第五步:对带参数的函数进行装饰
# -*- coding:gbk -*-
'''示例5: 对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
def deco(func):
def _deco(a, b):
print("before myfunc() called.")
ret = func(a, b)
print(" after myfunc() called. result: %s" % ret)
return ret
return _deco
@deco
def myfunc(a, b):
print(" myfunc(%s,%s) called." % (a, b))
return a + b
myfunc(1, 2)
myfunc(3, 4)
第六步:对参数数量不确定的函数进行装饰
# -*- coding:gbk -*-
'''示例6: 对参数数量不确定的函数进行装饰,
参数用(*args, **kwargs),自动适应变参和命名参数'''
def deco(func):
def _deco(*args, **kwargs):
print("before %s called." % func.__name__)
ret = func(*args, **kwargs)
print(" after %s called. result: %s" % (func.__name__, ret))
return ret
return _deco
@deco
def myfunc(a, b):
print(" myfunc(%s,%s) called." % (a, b))
return a+b
@deco
def myfunc2(a, b, c):
print(" myfunc2(%s,%s,%s) called." % (a, b, c))
return a+b+c
myfunc(1, 2)
myfunc(3, 4)
myfunc2(1, 2, 3)
myfunc2(3, 4, 5)
第七步:让装饰器带参数
# -*- coding:gbk -*-
'''示例7: 在示例4的基础上,让装饰器带参数,
和上一示例相比在外层多了一层包装。
装饰函数名实际上应更有意义些'''
def deco(arg):
def _deco(func):
def __deco():
print("before %s called [%s]." % (func.__name__, arg))
func()
print(" after %s called [%s]." % (func.__name__, arg))
return __deco
return _deco
@deco("mymodule")
def myfunc():
print(" myfunc() called.")
@deco("module2")
def myfunc2():
print(" myfunc2() called.")
myfunc()
myfunc2()
第八步:让装饰器带 类 参数
# -*- coding:gbk -*-
'''示例8: 装饰器带类参数'''
class locker:
def __init__(self):
print("locker.__init__() should be not called.")
@staticmethod
def acquire():
print("locker.acquire() called.(这是静态方法)")
@staticmethod
def release():
print(" locker.release() called.(不需要对象实例)")
def deco(cls):
'''cls 必须实现acquire和release静态方法'''
def _deco(func):
def __deco():
print("before %s called [%s]." % (func.__name__, cls))
cls.acquire()
try:
return func()
finally:
cls.release()
return __deco
return _deco
@deco(locker)
def myfunc():
print(" myfunc() called.")
myfunc()
myfunc()
第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器
# -*- coding:gbk -*-
'''mylocker.py: 公共类 for 示例9.py'''
class mylocker:
def __init__(self):
print("mylocker.__init__() called.")
@staticmethod
def acquire():
print("mylocker.acquire() called.")
@staticmethod
def unlock():
print(" mylocker.unlock() called.")
class lockerex(mylocker):
@staticmethod
def acquire():
print("lockerex.acquire() called.")
@staticmethod
def unlock():
print(" lockerex.unlock() called.")
def lockhelper(cls):
'''cls 必须实现acquire和release静态方法'''
def _deco(func):
def __deco(*args, **kwargs):
print("before %s called." % func.__name__)
cls.acquire()
try:
return func(*args, **kwargs)
finally:
cls.unlock()
return __deco
return _deco
# -*- coding:gbk -*-
'''示例9: 装饰器带类参数,并分拆公共类到其他py文件中
同时演示了对一个函数应用多个装饰器'''
from mylocker import *
class example:
@lockhelper(mylocker)
def myfunc(self):
print(" myfunc() called.")
@lockhelper(mylocker)
@lockhelper(lockerex)
def myfunc2(self, a, b):
print(" myfunc2() called.")
return a + b
if __name__=="__main__":
a = example()
a.myfunc()
print(a.myfunc())
print(a.myfunc2(1, 2))
print(a.myfunc2(3, 4))
学习python装饰器_Python装饰器学习(九步入门)相关推荐
- 圆方圆学院零基础入门学习Python(绝对干货,值得学习)
圆方圆学院零基础入门学习Python(绝对干货,值得学习) 链接: pan.baidu.com/s/1Shpd1G8L- 提取码: bup7
- 学习 Python 之 Pygame 开发魂斗罗(九)
学习 Python 之 Pygame 开发魂斗罗(九) 继续编写魂斗罗 1. 在子弹类中修改敌人发射子弹的位置 2. 创建显示敌人子弹的函数 3. 解决敌人不会向下掉落的问题 4. 给敌人碰撞体组增加 ...
- 小甲鱼零基础入门学习Python(绝对干货,值得学习)
小甲鱼零基础入门学习Python(绝对干货,值得学习) 链接: https://pan.baidu.com/s/1jJmIrlk 密码: ktp2
- python装饰器_Python装饰器是个什么鬼?
不知道大家的Python入门的怎么样了啊?后面几篇Python的文章涉及一些Python中高级的内容,建议还没入门的朋友好好阅读一下如何快速入门Python赶紧上车.后台回复"python& ...
- python两层装饰器_python装饰器
Python的装饰器的英文名叫Decorator,基本上适用的场景就是"装修":不涉及主流程业务,用于鉴权.审计等副业. 1.函数 在python中,函数通过def关键字.函数名和 ...
- python实现装饰器_python装饰器的实现
说起装饰器我们可能已经很熟悉了(不了解的可以查看python基础学习--装饰器),随手就可以写一个简单的装饰器 def decorator(func): def inner(*args, **kwar ...
- python find函数_Python 装饰器填坑指南 | 最常见的报错信息、原因和解决方案
本文为霍格沃兹测试学院学员学习笔记,进阶学习文末加群. Python 装饰器简介 装饰器(Decorator)是 Python 非常实用的一个语法糖功能.装饰器本质是一种返回值也是函数的函数,可以称之 ...
- python重写和装饰器_python装饰器
python装饰器的本质,就是闭包! 我们一般谈Python的闭包,都是指普通的入参,而谈装饰器的时候,入参一定有函数!闭包和装饰器,返回的都是函数.函数是代码的最小封装单位,装饰器作用于函数,它不影 ...
- python log函数_python装饰器的使用
1. 装饰者模式 装饰者模式是常用的软件设计模式之一.通过此设计模式,我们能够在不修改任何底层代码情况下,给已有对象赋予新的职责.python中可以用装饰器简单地实现装饰者模式. 1.1 将函数作为参 ...
- python解读器_Python装饰器完全解读
Python Python开发 Python语言 Python装饰器完全解读 1 引言 装饰器(Decorators)可能是Python中最难掌握的概念之一了,也是最具Pythonic特色的技巧,深入 ...
最新文章
- 趣谈NAT和防火墙的对话+防火墙静态PAT的应用
- 【论文知识点笔记】GNN概述(图神经网络概述)
- 如何异步提交表单 如何异步跨域提交表单
- python整型图_python源码研究之整型对象探索
- (转)搞定DC/DC电源转换方案设计,必看金律十一条
- Buffer对象与JSON对象相互转换
- C# TabControl增加关闭按钮
- Java-马士兵设计模式学习笔记-策略模式-模拟Comparable接口
- 前端json转对象和数组
- 勒索病毒免费解密工具都在这里!
- PS2018下载PSCC2018安装教程
- C 修改内存制作外挂
- html鼠标悬浮更换图片,Vue.js鼠标悬浮更换图片功能
- 80386 Programmer's Manual: Chapter 9 Exceptions and Interrupts(Personal Translation)
- p5js动漫角色临摹
- mac/windows下查看端口号占用情况以及杀死端口进程
- 主成分分析法及特征值的含义
- Eigen::aligned_allocator
- openjudge 1.3.10 计算并联电阻的阻值
- Python123分段函数计算
热门文章
- 共同创造最好的OS,openEuler Developer Day 报名通道开启
- Mybatis是如何实现SQL语句复用功能的?
- 缓存模式以及缓存的数据一致性
- MySQL中只会count(),sum()?累加运算没听过?
- Spring Cloud构建微服务架构:分布式服务跟踪(整合logstash)【Dalston版】
- mysql 5.6.20安装_Windows下面安装和配置MySQL(5.6.20)
- 04741计算机网络原理知识点,04741计算机网络原理知识点整理.doc
- points.checkVector(2, CV_32S) >= 0 in function ‘cv::fillConvexPoly‘
- torch分布式训练学习笔记
- OkHttp3 websocket