python闭包与装饰器
转自小马哥:
闭包和装饰器充分体现了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('', 4)))
print(counter(add(1, 5)))
print(counter(add(1, 6)))
结果:
>> long@happytime:~/development/closure$ python3 test.py
>> (, )
>> (, )
>> (, 'Invalid.')
>> (, )
>> (, )
虽然可以正确显示结果,但是有如下几个不满意的地方:
- 全局变量的使用首先是不提倡的;
- 每次调用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('', 4)))
print(ct(add(1, 5)))
print(ct(add(1, 6)))
结果:
>> long@happytime:~/development/closure$ python3 test1.py
>> (, )
>> (, )
>> (, 'Invalid.')
>> (, )
>> (, )
用装饰器进一步解决问题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('', 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('', 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闭包与装饰器的更多相关文章
- python 闭包和装饰器
python 闭包和装饰器 一.闭包闭包:外部函数FunOut()里面包含一个内部函数FunIn(),并且外部函数返回内部函数的对象FunIn,内部函数存在对外部函数的变量的引用.那么这个内部函数Fu ...
- 高逼格利器之Python闭包与装饰器
生活在魔都的小明,终于攒够了首付,在魔都郊区买了一套房子:有一天,小明踩了狗屎,中了一注彩票,得到了20w,小明很是欢喜,于是想干脆用这20万来装修房子吧(decoration): 整个装修过程,小明 ...
- Python—闭包和装饰器
闭包 定义:内部函数对外部函数变量的引用,则将该函数与用到的变量称为闭包. 闭包必须满足以下三个条件: 必须有一个内嵌函数. 内嵌函数必须引用外部函数中的变量. 外部函数返回值必须是内嵌函数的引用. ...
- Python 简明教程 --- 22,Python 闭包与装饰器
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...
- Python闭包及装饰器
Python闭包 先看一个例子: def outer(x): def inner(y): return x+y return innder add = outer(8) print add(6) 我们 ...
- python闭包以及装饰器
通俗的定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).它只不过是个“内层”的函数,由一个名字(变量)来指代,而这个名字(变 ...
- python闭包和装饰器
本文目录: 1. 闭包的解析和用法 2. 函数式装饰器 3. 类装饰器 一.闭包 闭包是一种函数,从形式上来说是函数内部定义(嵌套)函数,实现函数的扩展.在开发过程中,考虑到兼容性和耦合度问题,如果想 ...
- python闭包和装饰器(转)
一.python闭包 1.内嵌函数 >>> def func1(): ... print ('func1 running...') ... def func2(): ... prin ...
- 详解Python闭包,装饰器及类装饰器
在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...
随机推荐
- 无限轮播的N+2 策略
N张照片把contentsSize设置为N+2个图片的宽度,例子如下,两端填充如图,当处于一端时,且即将进入循环状态的时候,如第二张图,从状态1滑动到状态2,在滑动结束的时候,将当前的位置直接转到状态 ...
- August 22nd 2016 Week 35th Monday
Have you ever given any thought to your future? 你有没有为将来打算过呢? Have you ever given any thought to your ...
- mongodb 3.2 用户权限管理配置
使用mongodb 有段时间了,由于是在内网使用,便没有设置权限,一直是裸奔. 最近有时间,研究了下mongodb 3.2 的用户权限配置,网上有许多用户权限配置的文章,不过大多是之前版本,有些出入, ...
- 一分钟可知css3版大白源码
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- MD(markdown)语法
#标题1 ##标题2 段落->空行分隔 `加背景` [超链接](https://www.baidu.com) **加粗** _斜体_ ~~删除线~~ . 列表一 . 列表二 图片: ![alt ...
- cf378C(模拟)
题目链接:http://codeforces.com/contest/733/problem/C 思路:模拟 因为数组b里的元素是顺序对应a数组元素的和,可以开个c数组储存b数组元素对应的a数组元素区 ...
- Struts2拦截器之ModelDrivenInterceptor
叙述套路: 1.这是个啥东西,它是干嘛用的? 2.我知道它能干啥了,那它咋个用呢? 3.它能跑起来了,但是它是咋跑起来的是啥原理呢? 一.ModelDriven是个啥?他能做什么? 从前端页面到后端的 ...
- 20145206《Java程序设计》实验五Java网络编程及安全
20145206<Java程序设计>实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验步骤 我和201451 ...
- [LeetCode] Validate Binary Search Tree (两种解法)
Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...
- git中使用.gitignore文件
在进行协作开发代码管理的过程中,常常会遇到某些临时文件.配置文件.或者生成文件等,这些文件由于不同的开发端会不一样,如果使用git add . 将所有文件纳入git库中,那么会出现频繁的改动和push ...