1.什么是闭包函数

(1):什么是闭包函数:

#内部函数包含对外部作用域而非全局作用域的引用,

  简而言之, 闭包的特点就是内部函数引用了外部函数中的变量。 在Python中,支持将函数当做对象使用,也就是可以将一个函数当做普通变量一样用作另一个函数的参数和返回值。拥有此类特性的语言,一般都支持闭包。


  闭包中被内部函数引用的变量,不会因为外部函数结束而被释放掉,而是一直存在内存中,知道内部函数被调用结束。

#提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,包起来喽,包起呦,包起来哇

        def counter():
n=0
def incr():
nonlocal n
x=n
n+=1
return x
return incr c=counter()
print(c())
print(c())
print(c())
print(c.__closure__[0].cell_contents) #查看闭包的元素

(2)闭包函数的意义于应用:

#闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
#应用领域:延迟计算(原来我们是传参,现在我们是包起来)
from urllib.request import urlopen def index(url):
def get():
return urlopen(url).read()
return get baidu=index('http://www.baidu.com')
print(baidu().decode('utf-8'))

2.装饰器

  总而言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
一般而言,我们要想拓展原来函数代码,最直接的办法就是侵入代码里面修改

  本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。

  强调装饰器的原则:1 不修改被装饰对象的源代码

           2 不修改被装饰对象的调用方式

  装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

(1)装饰器的使用

  

import time
def timmer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper @timmer
def foo():
time.sleep(3)
print('from foo')
foo()

无参装饰器

def auth(driver='file'):
def auth2(func):
def wrapper(*args,**kwargs):
name=input("user: ")
pwd=input("pwd: ") if driver == 'file':
if name == 'egon' and pwd == '123':
print('login successful')
res=func(*args,**kwargs)
return res
elif driver == 'ldap':
print('ldap')
return wrapper
return auth2 @auth(driver='file')
def foo(name):
print(name) foo('Hello World')

有参装饰器

(2)装饰器的语法

被装饰函数的正上方,单独一行
@deco1
@deco2
@deco3
def foo():
pass foo=deco1(deco2(deco3(foo)))

(3)装饰器语法糖

import time

def outter(func):
# func = 最原始那个home的内存地址
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs) # 最原始那个home的内存地址()
end = time.time()
print('run time is %s' % (end - start))
return res return wrapper @outter # index = outter(index)
def index():
print('from index')
time.sleep(1) @outter # home = outter(home)
def home(name):
print('welcome %s to home page' % name)
time.sleep(0.5)
return 123 res = home('egon')
print(res)

装饰器语法糖

(4)叠加多个装饰器

# 叠加多个装饰器
# 1. 加载顺序(outter函数的调用顺序):自下而上
# 2. 执行顺序(wrapper函数的执行顺序):自上而下
def outter1(func1): #func1=wrapper2的内存地址
print('加载了outter1')
def wrapper1(*args,**kwargs):
print('执行了wrapper1')
res1=func1(*args,**kwargs)
return res1
return wrapper1 def outter2(func2): #func2=wrapper3的内存地址
print('加载了outter2')
def wrapper2(*args,**kwargs):
print('执行了wrapper2')
res2=func2(*args,**kwargs)
return res2
return wrapper2 def outter3(func3): # func3=最原始的那个index的内存地址
print('加载了outter3')
def wrapper3(*args,**kwargs):
print('执行了wrapper3')
res3=func3(*args,**kwargs)
return res3
return wrapper3 @outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
@outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
@outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
def index():
print('from index') print('======================================================')
index()

最新文章

  1. [转载]自己编写 php 在线问卷调查程序
  2. 关于jquery自带动画效果的stop()问题
  3. MySQL通用优化 叶金荣!!!
  4. sql server 2008 查询语句的红色波浪线
  5. Angular2 - Starter - Component and Component Lifecircle Hooks
  6. Linux学习笔记13——使用curses函数库
  7. css三角形绘制
  8. jvm之内存分配与回收策略
  9. Android开发之大位图二次採样压缩处理(源码分享)
  10. 我的云服务之WWW
  11. ajax的跨域请求
  12. python爬虫入门学习
  13. 关于阿里ICON矢量图(SVG)上传问题.
  14. Restful levels and Hateoas
  15. C语言顺序栈
  16. 一张图看Docker
  17. 《温故而知新》JAVA基础一
  18. android studio报Resolved versions for app (26.1.0) and test app (27.1.1)differ. 错误的解决办法
  19. dedecms自定义表单提交成功后提示信息修改和跳转链接修改
  20. 深度学习 目标检测算法 SSD 论文简介

热门文章

  1. 看完我的笔记不懂也会懂----ECMAscript 567
  2. Java编程开发之数据图表分析模型
  3. HDOJ-1024(动态规划+滚动数组)
  4. HDOJ-3065(AC自动机+每个模板串的出现次数)
  5. js mysql 时间日期比较
  6. Vulnhub dc-4靶机通关
  7. PHP题库1
  8. C# 应用 - 多线程 5) 死锁
  9. Jmeter 分布式架构和服务器性能监控解决方案
  10. 【关系抽取-R-BERT】加载数据集