在这点上闭包可以被理解为一个只读的对象 , 你可以给他传递一个属性,但它只能提供给你一个执行的接口 。因此在程序中我们经常需要这样的一个函数对象——闭包,来帮我们完成一个通用的功能,比如后面会提到的——装饰器 。
3. 使用闭包
第一种场景 ,在python中很重要也很常见的一个使用场景就是装饰器 , Python为装饰器提供了一个很友好的“语法糖”——@ , 让我们可以很方便的使用装饰器 , 装饰的原理不做过多阐述 , 简言之你在一个函数func上加上@decorator_func, 就相当于decorator_func(func):
复制代码代码如下:
def decorator_func(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@decorator_func
def func(name):
print 'my name is', name
# 等价于
decorator_func(func)
在装饰器的这个例子中,闭包(wrapper)持有了外部的func这个参数 , 并且能够接受外部传过来的参数,接受过来的参数在原封不动的传给func,并返回执行结果 。
这是个简单的例子,稍微复杂点可以有多个闭包 , 比如经常使用的那个LRUCache的装饰器,装饰器上可以接受参数@lru_cache(expire=500)这样 。实现起来就是两个闭包的嵌套:
复制代码代码如下:
def lru_cache(expire=5):
# 默认5s超时
def func_wrapper(func):
def inner(*args, **kwargs):
# cache 处理 bala bala bala
return func(*args, **kwargs)
return inner
return func_wrapper
@lru_cache(expire=10*60)
def get(request, pk)
# 省略具体代码
return response()
不太懂闭包的同学一定得能够理解上述代码,这是我们之前面试经常会问到的面试题 。
第二个场景,就是基于闭包的一个特性——“惰性求值” 。这个应用比较常见的是在数据库访问的时候,比如说:
复制代码代码如下:
# 伪代码示意
class QuerySet(object):
def __init__(self, sql):
self.sql = sql
self.db = Mysql.connect().corsor()# 伪代码
def __call__(self):
return db.execute(self.sql)
def query(sql):
return QuerySet(sql)
result = query("select name from user_app")
if timenow:
print result# 这时才执行数据库访问
上面这个不太恰当的例子展示了通过闭包完成惰性求值的功能,但是上面query返回的结果并不是函数,而是具有函数功能的类 。有兴趣的可以去看看Django的queryset的实现,原理类似 。
第三种场景 ,需要对某个函数的参数提前赋值的情况,当然在Python中已经有了很好的解决访问 functools.parial,但是用闭包也能实现 。
复制代码代码如下:
def partial(**outer_kwargs):
def wrapper(func):
def inner(*args, **kwargs):
for k, v in outer_kwargs.items():
kwargs[k] = v
return func(*args, **kwargs)
return inner
return wrapper
@partial(age=15)
def say(name=None, age=None):
print name, age
say(name="the5fire")
# 当然用functools比这个简单多了
# 只需要: functools.partial(say, age=15)(name='the5fire')
看起来这又是一个牵强的例子,不过也算是实践了闭包的应用 。
Python中什么是闭包?Python中的闭包不是一个简单一说就能明白的概念,这个是需要在深入学习当中理解的 。在一些语言中,函数中可以嵌套定义另外一个 , 如果内部函数引用python举例函数闭包了外部函数的变量,就会产生闭包 。闭包是可以用在一个函数与一组私有的变量之间创建关联关系 。在给定函数中被多次调用的,这些私有变量能够保持持久性python举例函数闭包;
推荐阅读
- 洗发露沐浴乳直播文案,沐浴露洗发水的广告句子
- 图片展开的js特效代码,图片展开的js特效代码
- 区块链与版权保护,区块链与版权保护的关系
- 毕业设计搜图软件哪个好,毕业设计的app
- mysql怎么系统学习的简单介绍
- gis中od,gis中od分析有的点没有连接
- java类测试代码 java测试项目
- 包含蜜芽ios系统的词条
- 孩子迷恋什么网络游戏,孩子迷恋网络游戏的原因