返回顶部
首页 > 资讯 > 后端开发 > Python >Python闭包技巧介绍
  • 196
分享到

Python闭包技巧介绍

2024-04-02 19:04:59 196人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录1.闭包:用函数代替类2.访问定义在闭包的内的变量1.闭包:用函数代替类 有时我们会定义只有一个方法(除了__init__()之外)的类,而这种类可以通过使用闭包(closur

1.闭包:用函数代替类

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


from urllib.request import urlopen
class 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 opener

yahoo = 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 = 0
f.set_n(10)
f() # n = 10
print(f.get_n()) # 10


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

示例如下:


import sys
class 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 use
def 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)) # 3
print(s.pop()) # Hello
print(s.pop()) # 20
print(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 timeit
s = Stack()
print(timeit('s.push(1);s.pop()', 'from __main__ import s'))
# 0.98746542
s = Stack2()
print(timeit('s.push(1);s.pop()', 'from __main__ import s'))
# 1.07070521


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

到此这篇关于python闭包技巧介绍的文章就介绍到这了,更多相关Python闭包内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python闭包技巧介绍

本文链接: https://lsjlt.com/news/159062.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python闭包技巧介绍
    目录1.闭包:用函数代替类2.访问定义在闭包的内的变量1.闭包:用函数代替类 有时我们会定义只有一个方法(除了__init__()之外)的类,而这种类可以通过使用闭包(closur...
    99+
    2024-04-02
  • Python闭包技巧是什么
    这篇文章主要讲解了“Python闭包技巧是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python闭包技巧是什么”吧!1.闭包:用函数代替类有时我们会定义只有一个方法(除了__init...
    99+
    2023-06-21
  • Python函数对象与闭包介绍
    目录一 函数对象1.1 函数可以被引用1.2 函数可以作为容器类型的元素1.3 函数可以作为参数传入另外一个函数1.4 函数的返回值可以是一个函数二 闭包函数2.1 闭与包2.2 闭...
    99+
    2024-04-02
  • JavaScript闭包的简单介绍
    本篇内容主要讲解“JavaScript闭包的简单介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript闭包的简单介绍”吧!什么是JS闭包?先看一...
    99+
    2024-04-02
  • 分享介绍Python的9个实用技巧
    本文会介绍一些Python大神用的贼溜的技巧,让一探究竟吧!欢迎收藏学习,喜欢点赞支持,欢迎畅聊。 整理字符串输入 整理用户输入的问题在编程过程中很常见。有更好的方法来解决: u...
    99+
    2024-04-02
  • Python写代码的七条重要技巧介绍
    目录前言0x00 规范命名0x01 面向对象0x02 使用 with0x03 使用 get0x04 提前返回0x05 生成...
    99+
    2024-04-02
  • JavaScript闭包原理与使用介绍
    目录1. 认识闭包2. 变量的作用域和生命周期2.1 变量的作用域2.2 变量的生命周期3. 闭包的概念及其作用3.1 闭包的概念3.2 闭包的应用3.2.1 保存私有变量3.2.2...
    99+
    2022-11-13
    JavaScript闭包 JS闭包
  • Windows 8技巧:Windows 8中FlipView的使用技巧介绍
      FlipView控件类似于翻页控件,并且是现成的翻页按钮,你只需要为其增加数据项即可。本文讲述两种方式的FlipView项目和展示。   一:直接前台FlipViewItem复制代码代码如下:<F...
    99+
    2022-06-04
    使用技巧 技巧 Windows
  • 优化Python中len函数的性能技巧介绍
    了解Python中len函数的性能优化技巧,需要具体代码示例 Python是一种简单易学的高级编程语言,被广泛应用于数据处理、科学计算、机器学习等领域。在Python中,len函数是一个常用的函数,用于获取容器(如列表、元组、字...
    99+
    2024-01-13
    Python 性能优化 len函数
  • Wordpress被忽略的SEO技巧介绍
    很多时候,我们做网站时在本身网站没有完全架构好就去寻找所谓的SEO技巧。这往往是本末倒置。就拿wordpress来说,本身的SEO优化已经做的非常好,甚至细节都帮我们考虑到了。而这些细节经常被我们忽略。本文将从一个小细节...
    99+
    2022-06-12
    Wordpress SEO技巧
  • 纯CSS布局排版技巧介绍
    本篇内容主要讲解“纯CSS布局排版技巧介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“纯CSS布局排版技巧介绍”吧!开发每一张网页都离不开布局排版,基于良好布...
    99+
    2024-04-02
  • PostgreSQL常用优化技巧示例介绍
    目录1、标量子查询与filter2、视图合并3、谓词推入1、标量子查询与filter 当一个查询在select和from之间,那么这种子查询就是标量子查询。实际应用中,很多人在写SQL时为了方便会写一堆标量子查...
    99+
    2024-04-02
  • 操作JS字符串的技巧介绍
    本篇内容介绍了“操作JS字符串的技巧介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!JavaScript...
    99+
    2024-04-02
  • XP桌面文字技巧使用介绍
    ★其实还可以按住Alt键,然后在小键盘输入“0160”,这样也可以达到同样效果。 ★若找不到内码输入法,可右击输入法切换图标选择“设置”,再单击“添加&rdqu...
    99+
    2023-06-01
    XP桌面 文字技巧 技巧 桌面 XP
  • JavaScript的闭包与变量作用域介绍
    这篇文章主要讲解了“JavaScript的闭包与变量作用域介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript的闭包与变量作用域介绍”吧!...
    99+
    2024-04-02
  • JavaScript 闭包的技巧:掌握高级编程技术
    闭包是JavaScript中强大的技术,它允许函数访问在其创建时存在的外部变量,即使函数执行完毕。掌握闭包的技巧可以显着提高您的代码的灵活性、可维护性和性能。 1. 利用闭包进行数据封装 闭包可以用于封装数据,使其私有化并只对创建它们的函...
    99+
    2024-03-14
    闭包
  • 最实用Win7技巧快捷操作介绍
    Win7的桌面设置更加个性化,我们的照片、喜欢的壁纸,都可以随时设为背景,而女生们的桌面壁纸很多都比较卡哇伊,但如果去做演示时,投射到投影公示,也许就会带来一些尴尬。其实在演示前,我们只需要通过Win+X快捷键打开移动中...
    99+
    2023-05-26
    Win7技巧 快捷操作 操作 技巧 Win7
  • Windows 7系统70个小技巧的介绍
     1. 电脑守卫  我很少让其他人使用我的电脑,因为我怕他们会把它弄的乱七八糟的,但是看起来,微软已经替我考虑到这一点并且顺便解决了这个问题。PC Safeguard不会让任何人把你电脑的设置弄乱,因为当他们注销的时候,...
    99+
    2023-05-25
    小技巧 Windows 7 技巧 介绍
  • ASP.NETCoreWeb资源打包与压缩技术介绍
    概述 在ASP.Net中可以使用打包与压缩这两种技术来提高Web应用程序页面加载的性能。通过减少从服务器请求的次数和减少资源文件的体积来提高加载性能。 打包是一地将多个文件(CSS,...
    99+
    2024-04-02
  • 帝国CMS的采集常用小技巧介绍
    本节建站教程是关于采集使用的技巧,大家可以借鉴一下: 1、过滤文章内容的链接: 广告正则:“<a [!--ad--]>”;替换“</a>”...
    99+
    2022-06-12
    帝国采集技巧
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作