首页 > 编程问答 >在 Python 生成器中使用“with”语句管理资源

在 Python 生成器中使用“with”语句管理资源

时间:2024-08-02 04:37:54浏览次数:8  
标签:python yield with-statement

今天,在编程时,我发现自己在生成器函数内管理资源(ssh 连接),类似于以下内容:

def _yield_fname(host_address, usr, pwd, datapath):
    with paramiko.SSHClient() as ssh_client:

        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_client.connect(host, username=usr, password=pwd)
        
        stdin, stdout, stderr = ssh_client.exec_command(
            'find . -type d -maxdepth 1 -printf "%f\n"'
        )
        for line in stdout:
            yield fname

def get_foos():

    foos= []
    for fname in self._yield_fname(self.FOO_PATH):
        foos.append(Foo.from_fname(fname))
    
    return foos

def get_bars():

    bars= []
    for fname in self._yield_fname(self.FOO_PATH):
        bars.append(Bar.from_fname(fname))
    
    return bars

以这种方式管理生成器函数内的资源是不好的做法吗?

在我的在这种情况下,我计划从开始到结束始终消耗 yield_fname 的生成器,以便连接始终关闭。我是否应该担心有人(例如未来的我)使用生成器而没有完全消耗它并保持连接打开?有没有办法防止这种情况?

(作为旁注,这里我决定使用生成器函数,因为我想避免循环遍历文件名列表两次或更多次)。


你的代码展示了在 Python 生成器中使用 with 语句管理资源的完美有效且推荐的方式。 事实上,这是处理此类情况的最佳方法之一。

让我们分解一下为何如此以及为何你不必担心资源泄漏:

  1. with 语句和上下文管理器: with 语句与上下文管理器(如 paramiko.SSHClient )相结合,可确保即使在发生错误或生成器未完全耗尽的情况下也能正确清理资源。 当执行离开 with 块时,无论正常退出还是通过异常退出,都会自动调用上下文管理器的 __exit__ 方法。 在你的情况下,这会保证关闭 SSH 连接。

  2. 生成器不会阻止清理: 你是对的,生成器在理论上可以让你在不完全迭代完的情况下停止迭代,从而可能使资源处于打开状态。 但是, with 语句与生成器的工作方式无关。 即使生成器未完全耗尽,当执行离开 with 块时, with 块仍会保证调用清理代码( __exit__ 方法)。

  3. 你的使用场景: 在你的情况下,你提到你始终打算完全消耗生成器。 这很好,但这不会改变 with 语句带来的安全性和便利性。 它充当了一个安全网,即使在未来代码行为发生变化或出现意外异常的情况下也能确保正确清理。

简而言之,在你的生成器函数中使用 with 语句来管理 SSH 连接是一种干净且 Pythonic 的方法,并且你无需担心资源泄漏,即使生成器未完全耗尽也是如此。 with 语句为你提供了保障。

此外,使用生成器来避免多次循环遍历文件名的决定是一个很好的优化,可以提高代码的效率。

如果你想在代码中添加额外的防御层,可以考虑添加一些日志记录或在 __exit__ 方法中进行断言,以验证在离开 with 块时资源是否已正确关闭。 但这对于你的情况来说可能有点过分了,因为 with 语句已经为你处理得很好。

标签:python,yield,with-statement
From: 78822299

相关文章

  • Avro:在 Python 中使用多处理进行解码
    就最佳性能和更少延迟而言,哪种异步方法更适合解码从Kafka主题消耗的Avro消息?我正在使用Avro库的并发future,并且我仍然可以看到类似的执行时间与不使用并发future的情况相比。fromavro.ioimportBinaryDecoder,DatumReaderfromconfluent_kafka.avro.cached_sc......
  • 白盒测试基础与实践:Python示例及流程图设计
    文章目录前言一、白盒测试是什么?主要特点常用方法优点缺点二、白盒测试常用技术语句覆盖判定覆盖条件覆盖判定/条件覆盖条件组合覆盖路径覆盖三、程序流程图设计四、测试用例设计1.基本路径法2.语句覆盖3.判断覆盖4.条件覆盖5.判断/条件覆盖6.条件组合覆盖总结......
  • 【python的语法特点,如注释规则、代码缩进、编写规范等】
    介绍一下python的语法特点,如注释规则、代码缩进、编写规范等Python是一种广泛使用的高级编程语言,以其简洁易读的语法、丰富的标准库和强大的第三方库而闻名。下面我将详细介绍Python的一些基本语法特点,包括注释规则、代码缩进、以及编写规范等。一、注释规则Python......
  • 深圳大学-数据科学导论实验-python数据探索
    实验目的与要求掌握python编程基础。掌握数据探索基本操作。实验环境WindowsPyCharm实验数据salaries.csv"","rank","discipline","yrs.since.phd","yrs.service","sex","salary""1","Prof","B",......
  • 基于Python+Django协同过滤算法的招聘信息推荐系统设计与实现(源码+数据库+讲解)
    文章目录前言详细视频演示项目运行截图技术框架后端采用Django框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • python 栈帧沙箱逃逸
    基础理论什么是生成器生成器是python中的一种特殊的迭代器,在每次生成值以后会保留当前状态,以便下次调用可以继续生成值.python中生成器通过yield关键词进行定义,每次调用的时候返回一个值,并保持当前状态的同时暂停函数的执行.当下一次调用生成器的时候,函数会从上次暂停的位......
  • Transformer预测模型及其Python和MATLAB实现
    ###一、背景在自然语言处理(NLP)领域,传统的序列到序列(Seq2Seq)模型大多依赖于循环神经网络(RNN)和长短期记忆(LSTM)网络。这些模型虽然在许多任务中取得了成功,但由于其计算效率低下以及长距离依赖关系处理的不足,导致模型训练时间漫长,并在处理较长文本时效果不佳。2017年,Vaswani等人......
  • 随机森林(Random Forest)预测模型及其特征分析(Python和MATLAB实现)
    ##一、背景在大数据和机器学习的快速发展时代,数据的处理和分析变得尤为重要。随着多个领域积累了海量数据,传统的统计分析方法常常无法满足复杂问题的需求。在这种背景下,机器学习方法开始广泛应用。随机森林(RandomForest)作为一种强大的集成学习方法,因其高效性和较强的泛化能......
  • 【python脚本打包成exe】
    python项目打包成exe安装包分为三部分:1.python项目打包成可执行文件,依赖于一个python插件包pyinstaller        通过pipinstallpyinstaller安装即可。2.将python项目打包成可执行的exe文件及其依赖包        2.1在项目根目录下,输出python项目的配置文件(x......
  • 在Python中,如果想要获取昨天和前天的日期时间,使用datetime模块中的datetime.now()来获
    问:在Python中,如果想要获取昨天和前天的日期时间,使用datetime模块中的datetime.now()来获取当前时间,然后通过减去相应的时间差来得到昨天和前天的日期时间答:在Python中,如果你想要获取昨天和前天的日期时间,你可以使用datetime模块中的datetime.now()来获取当前时间,然后通过减去相......