千家信息网

Python闭包技巧是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要讲解了"Python闭包技巧是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Python闭包技巧是什么"吧!1.闭包:用函数代替类有时
千家信息网最后更新 2026年11月01日Python闭包技巧是什么

这篇文章主要讲解了"Python闭包技巧是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Python闭包技巧是什么"吧!

1.闭包:用函数代替类

有时我们会定义只有一个方法(除了__init__()之外)的类,而这种类可以通过使用闭包(closure)来替代。闭包是被外层函数包围的内层函数,它能够获取外层函数范围中的变量(即使外层函数已执行完毕)。因此闭包可以保存额外的变量环境,用于在函数调用时使用。考虑下面这个例子,这个类允许用户通过某种模板方案来获取URL。

from urllib.request import urlopenclass UrlTemplate:     def __init__(self, template) -> None:         self.template = template     def open(self, **kwargs):         return urlopen(self.template.format_map(kwargs))     yahoo = UrlTemplate('http://finance.yahoo.com/d/quotes.csv?s={names}&f={fields}') for line in yahoo.open(names='IBM,AAPL,FB', fields = 'sllclv'):     print(line.decode('utf-8'))

这个类可以用一个简单的函数来替代:

def urltempalte(template):    # 后面用对象再次调用函数的时候传入kwargs    def opener(**kwargs):        return urlopen(template.format_map(kwargs))    return openeryahoo = urltempalte('http://finance.yahoo.com/d/quotes.csv?s={names}&f={fields}')for line in yahoo(names='IBM,AAPL,FB', fields = 'sllclv'):    print(line.decode('utf-8'))

在许多情况下,我们会使用只有单个方法的类的原因是需要保存额外的状态给类方法使用。我们上面提到的UrlTemplate类的唯一目的就是将template的值保存在某处,然后在open()方法中使用它。而使用闭包来解决该问题会更加简短和优雅,我们使用opener()函数记住参数template的值,然后再随后的调用中使用该值。
所以大家在编写代码中需要附加额外的状态给函数时,一定要考虑使用闭包。

2.访问定义在闭包的内的变量

我们知道闭包内层可以用来存储函数需要用到的变量环境。接下来,我们可以通过函数来扩展闭包,使得在闭包内层定义的变量可以被访问和修改。
一般来说,闭包内层定义的变量对外界来说是完全隔离的,如果想要访问和修改它们,需要编写存取函数(accessor function, 即getter/setter方法),并将它们做为函数属性附加到闭包上来提供对内层变量的访问支持:

def sample():    n = 0    # 闭包函数    def func():        print("n =", n)        # 存取函数(accessor function),即getter/setter方法    def get_n():        return n    def set_n(value):        # 必须要加nolocal才能修改内层变量        nonlocal n        n = value    # 做为函数属性附加    func.get_n = get_n    func.set_n = set_n    return func

该算法测试运行结果如下:

f = sample()f() # n = 0f.set_n(10)f() # n = 10print(f.get_n()) # 10

可以看到,get_n()和set_n()工作起来很像实例的方法。注意一定要将get_n()和set_n()做为函数属性附加上去,否则在调用set_n()和get_n()就会报错:'function' object has no attribute 'set_n'。
如果我们希望让闭包完全模拟成类实例,我们需要架构内层函数拷贝到一个实例的字典中然后将它返回。

示例如下:

import sysclass ClosureInstance:    def __init__(self, locals=None) -> None:        if locals is None:            locals = sys._getframe(1).f_locals                     # Update instance dictionary with callables        self.__dict__.update(            (key, value) for key, value in locals.items() if callable(value)        )    # Redirect special methods    def __len__(self):        return self.__dict__['__len__']()    # Example usedef Stack():    items = []    def push(item):        items.append(item)        def pop():        return items.pop()        def __len__():        return len(items)        return ClosureInstance()

下面展示了对应的测试结果:

s = Stack()print(s) # <__main__.ClosureInstance object at 0x101efc280>s.push(10)s.push(20)s.push('Hello')print(len(s)) # 3print(s.pop()) # Helloprint(s.pop()) # 20print(s.pop()) # 10

用闭包模型类的功能比传统的类实现方法要快一些。比如我们用下面这个类做为测试对比。

class Stack2:    def __init__(self) -> None:        self.items = []        def push(self, item):        self.items.append(item)    def pop(self):        return self.items.pop()        def __len__(self):        return len(self.items)

下面是我们的测试结果:

from timeit import timeits = Stack()print(timeit('s.push(1);s.pop()', 'from __main__ import s'))# 0.98746542s = Stack2()print(timeit('s.push(1);s.pop()', 'from __main__ import s'))# 1.07070521

可以看到采用闭包的版本要快大约8%。因为对于实例而言,测试话费的大部分时间都在对实例变量的访问上,而闭包要更快一些,因为不用涉及额外的self变量。
不过这种奇技淫巧在代码中还是要谨慎使用,因为相比一个真正的类,这种方法其实是相当怪异的。像继承、属性、描述符或者类方法这样的特性在这种方法都是无法使用的。而且我们还需要一些花招才能让特殊方法正常工作(比如我们上面ClosureInstance中对__len__()的实现)。不过,这仍然是一个非常有学术价值的例子,它告诉我们对闭包内部提供访问机制能够实现怎样的功能。

感谢各位的阅读,以上就是"Python闭包技巧是什么"的内容了,经过本文的学习后,相信大家对Python闭包技巧是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

闭包 函数 方法 变量 内层 实例 测试 技巧 属性 附加 外层 结果 学习 代码 例子 内容 功能 只有 可以通过 就是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海喔噻互联网科技有限公司 互联网最新的科技 互联网科技与金融科技 互联网科技集团 互联网科技股有哪些 西藏七维空间互联网科技有限公司 广州慧亚互联网科技怎么样 阿里巴巴算科技企业还是互联网 银川新华互联网科技职业技术培训学校图片 深圳育鹏互联网科技有限公司招聘 乌苏新华互联网科技做什么的 华夏恒生科技与互联网科技 黑云互联网科技有限公司 图游互联网科技 互联网风格科技公司名称 万物互联网智能科技 中国互联网公司的科技投入 第三届互联网大会安防黑科技 陕西彩京云互联网科技有限公司 互联网科技自媒体灵感 深圳市人人互联网科技有限公司 互联网科技工作委员会 中国互联网科技工作委员会毛军 关于新基建和互联网科技 亿人帮互联网科技 镁科技互联网资讯平台 哈尔滨秒房互联网科技有限公司 互联网汽车科技小镇 青岛易易互联网科技 上海旺乐尼互联网科技有限公司
0