python闭包与装饰器
2015-12-13 18:39
579 查看
转自小马哥:
闭包和装饰器充分体现了Python语法糖的优雅感觉。
在本文中,我们的实验要完成两个工作,一个是加法,一个是累计调用加法的次数,最普通的Python程序可以这么写:
结果:
虽然可以正确显示结果,但是有如下几个不满意的地方:
全局变量的使用首先是不提倡的;
每次调用add都需要手动调用counter;
add函数和validate函数耦合在一起,如果以后需要判断更多条件,会产生很多层的if-else的嵌套。
用闭包解决问题1:
结果:
用装饰器进一步解决问题2:
结果:
用装饰器进一步解决问题3:
结果:
运用装饰器,可以在执行add的同时做很多事情,但耦合度很低,需要就加上装饰器,不需要就去掉。不过需要注意的是,多个装饰器的调用顺序是从下到上。所以@validate在@counter的下面。
闭包和装饰器充分体现了Python语法糖的优雅感觉。
在本文中,我们的实验要完成两个工作,一个是加法,一个是累计调用加法的次数,最普通的Python程序可以这么写:
def validate(a, b): if ((isinstance(a, int) or isinstance(a, float)) and (isinstance(b, int) or isinstance(b, float))): return True return False def add(a, b): if validate(a, b): return a + b return "Invalid." count = 0 def counter(func): global count count = count + 1 return (count, func) print(counter(add(1, 2))) print(counter(add(1, 3))) print(counter(add('1', 4))) print(counter(add(1, 5))) print(counter(add(1, 6)))
结果:
>> long@happytime:~/development/closure$ python3 test.py >> (1, 3) >> (2, 4) >> (3, 'Invalid.') >> (4, 6) >> (5, 7)
虽然可以正确显示结果,但是有如下几个不满意的地方:
全局变量的使用首先是不提倡的;
每次调用add都需要手动调用counter;
add函数和validate函数耦合在一起,如果以后需要判断更多条件,会产生很多层的if-else的嵌套。
用闭包解决问题1:
def validate(a, b): if ((isinstance(a, int) or isinstance(a, float)) and (isinstance(b, int) or isinstance(b, float))): return True return False def add(a, b): if validate(a, b): return a + b return "Invalid." def counter(): ct = 0 def do(func): nonlocal ct ct = ct + 1 return (ct, func) return do ct = counter() print(ct(add(1, 2))) print(ct(add(1, 3))) print(ct(add('1', 4))) print(ct(add(1, 5))) print(ct(add(1, 6)))
结果:
>> long@happytime:~/development/closure$ python3 test1.py >> (1, 3) >> (2, 4) >> (3, 'Invalid.') >> (4, 6) >> (5, 7)
用装饰器进一步解决问题2:
def validate(a, b): if ((isinstance(a, int) or isinstance(a, float)) and (isinstance(b, int) or isinstance(b, float))): return True return False def counter(func): ct = 0 def count(a, b): nonlocal ct ct = ct + 1 return (ct, func(a, b)) return count @counter def add(a, b): if validate(a, b): return a + b return "Invalid." print(add(1, 2)) print(add(1, 3)) print(add('1', 4)) print(add(1, 5)) print(add(1, 6))
结果:
>> long@happytime:~/development/closure$ python3 test2.py >> (1, 3) >> (2, 4) >> (3, 'Invalid.') >> (4, 6) >> (5, 7)
用装饰器进一步解决问题3:
def validate(func): def do(a, b): if ((isinstance(a, int) or isinstance(a, float)) and (isinstance(b, int) or isinstance(b, float))): return func(a, b) return "Invalid." return do def counter(func): ct = 0 def count(a, b): nonlocal ct ct = ct + 1 return (ct, func(a, b)) return count @counter @validate def add(a, b): return a + b print(add(1, 2)) print(add(1, 3)) print(add('1', 4)) print(add(1, 5)) print(add(1, 6))
结果:
>> long@happytime:~/development/closure$ python3 test3.py >> (1, 3) >> (2, 4) >> (3, 'Invalid.') >> (4, 6) >> (5, 7)
运用装饰器,可以在执行add的同时做很多事情,但耦合度很低,需要就加上装饰器,不需要就去掉。不过需要注意的是,多个装饰器的调用顺序是从下到上。所以@validate在@counter的下面。
相关文章推荐
- Python xlwt设置excel单元格字体及格式
- 批量修改文件名和后缀名的python设计
- 【Python】利用setdefault函数实现dict的转置(key与value对互换),统计value出现的次数
- NAO机器人之开发环境搭建
- 我的python笔记
- 怎样使用 Python 来判断一个路径是否存在判断一个路径是文件还是目录
- 【Python】无须numpy,利用map函数与zip(*)函数对数组转置
- Python 装饰器学习心得
- python3.5读取网页代码,并保存
- 04 Python正则表达式 爬虫程序 变量的引用,浅拷贝,深拷贝 多线程 进程锁 数据库模块
- Python3切换华为hi link设备数据开关
- 分享Python字符串关键点
- python 多线程学习
- 03 Python 文件系统 访问权限 函数 类与面向对象 自定义模块
- Python实时获取cmd的输出
- [从头学python] 第03节 让我们来学习math
- python中的算术操作符
- 【Python】Mysql中文乱码问题与MySQLdb对Mysql操作类的改进
- python 安装selenium环境
- python异常记录