从 Python 中的“with”块中进行屈服是否安全(以及为什么)?

2024-03-09

协程和资源获取的结合似乎可能会产生一些意想不到的(或不直观的)后果。

基本问题是这样的方法是否有效:

def coroutine():
    with open(path, 'r') as fh:
        for line in fh:
            yield line

确实如此。 (你可以测试一下!)

更深层的担忧是with应该是替代品finally,您可以确保在块末尾释放资源。协程可以暂停和恢复执行within the with块,所以冲突如何解决?

例如,如果在协程尚未返回时打开一个在协程内部和外部都具有读/写功能的文件:

def coroutine():
    with open('test.txt', 'rw+') as fh:
        for line in fh:
            yield line

a = coroutine()
assert a.next() # Open the filehandle inside the coroutine first.
with open('test.txt', 'rw+') as fh: # Then open it outside.
    for line in fh:
        print 'Outside coroutine: %r' % repr(line)
assert a.next() # Can we still use it?

Update

在前面的示例中,我打算进行写锁定文件句柄争用,但由于大多数操作系统为每个进程分配文件句柄,因此不会出现争用。 (感谢 @Miles 指出这个例子没有太大意义。)这是我修改后的例子,它显示了真正的死锁条件:

import threading

lock = threading.Lock()

def coroutine():
    with lock:
        yield 'spam'
        yield 'eggs'

generator = coroutine()
assert generator.next()
with lock: # Deadlock!
    print 'Outside the coroutine got the lock'
assert generator.next()

我真的不明白你要问什么冲突,也不明白这个例子的问题:同一个文件有两个共存、独立的句柄很好。

我在回答你的问题时不知道的一件事是,生成器上有一个新的 close() 方法:

close()提出了一个新的GeneratorExit生成器内部出现异常以终止迭代。收到此异常后,生成器的代码必须引发GeneratorExit or StopIteration.

close()当生成器被垃圾收集时被调用,因此这意味着生成器的代码在生成器被销毁之前有最后一次运行机会。这最后的机会意味着try...finally现在可以保证生成器中的语句有效;这finally子句现在总是有机会运行。这看起来像是一个很小的语言琐事,但是使用生成器和try...finally实际上有必要为了实施withPEP 343 描述的声明。

http://docs.python.org/whatsnew/2.5.html#pep-342-new-generator-features http://docs.python.org/whatsnew/2.5.html#pep-342-new-generator-features

这样就可以处理以下情况:with语句在生成器中使用,但它在中间产生但从未返回——上下文管理器的__exit__当生成器被垃圾收集时,将调用该方法。


Edit:

关于文件句柄问题:我有时会忘记存在不类似 POSIX 的平台。 :)

就锁而言,我认为 Rafał Dowgird 所说的“你只需要意识到发电机就像任何其他拥有资源的物体一样”一语中的。我不认为with语句在这里确实很相关,因为这个函数也遇到了同样的死锁问题:

def coroutine():
    lock.acquire()
    yield 'spam'
    yield 'eggs'
    lock.release()

generator = coroutine()
generator.next()
lock.acquire() # whoops!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 Python 中的“with”块中进行屈服是否安全(以及为什么)? 的相关文章

随机推荐

  • Typescript/babel 导入导致“_1.default 不是函数”

    我正在尝试使用https github com timmywil panzoom https github com timmywil panzoom来自使用 webpack 和 babel 编译的 typescript 项目 问题是打字稿方
  • 自定义树视图

    有没有办法自定义 winform 树视图以获得类似的东西 目的是通过父项目使用一种颜色并定义一个三角形而不是 图标来开发项目 Use TreeViewDrawMode OwnerDrawText所以缩进将由TreeView 除此之外 你应该
  • ::ng-deep 将被弃用 - 有其他选择吗?

    医生说 阴影穿透后代组合器已被弃用 并且主要浏览器和工具正在删除支持 因此 我们计划放弃对 Angular 的支持 对于 deep gt gt gt 和 ng deep 的所有 3 个 在那之前 应该首选 ng deep 以获得与工具更广泛
  • 在 JBoss 上部署 Hibernate 应用程序时出错 - 找不到适用于 jdbc 的驱动程序

    我有一个 Spring Hibernate Web 应用程序 目前在 Tomcat 上运行良好 我正尝试将其部署到 JBoss 7 1 AS 应用程序全部正确启动 但如果我设置 Hibernate Persistence 设置来创建表 则会
  • 如何使用冒号解组 XML 属性?

    我正在使用的一些 SVG XML 文件的属性名称中包含破折号和冒号 例如
  • 如何使用 jasmine 测试 $window.open

    这是我的功能 scope buildForm function majorObjectId name window open FormBuilder Index scope currentAppId form majorObjectId n
  • 如何在 perl 中创建多维数组?

    我这样创建一个多维数组 usr bin perl use warnings use strict my a1 1 2 my a2 a1 3 但事实证明我仍然得到一个一维数组 Perl 中正确的方法是什么 你得到一个一维数组 因为数组 a1在
  • 让 Collections.binarySearch() 与 CompareToIgnoreCase 一起使用?

    因此 我正在一个巨大的 ArrayList 中搜索特定的 String 值 但如果我正在查找的 String 与我传递给的 String 相等 不区分大小写 我需要 Collections binarySearch 返回一个 gt 0 的值
  • 如何使用 jQuery 获取文本输入的所有值?

    我有一个表 其中有一列预先填充的文本输入 table tr td td td td tr table
  • 如何将 zip 文件上传到 azure blob,然后在那里解压缩 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我有很多 zip 文件 其中只有几个文件夹和 50 多个文件 如何将这些 zip 文件上传到 azure blob 然后在那里解压缩 将服务
  • mvc c# html.dropdownlist 和 viewbag

    所以我有以下 伪代码 string selectedvalud C List
  • 如何在node.js模块中实现继承?

    我正在编写 Nodejs 应用程序 它基于expressjs 我对在 Nodejs 模块中进行继承感到困惑 我想做的是创建一个模型基类 比方说 my model js module exports function my model my
  • 在 C# 中提取 .cab 文件

    我正在开发一个 C 应用程序 我需要提取一个 cab 文件 我找不到在 C 中执行此操作的库 由于许可问题 我无法使用 Microsoft Deployment Compression Cab dll I found this https
  • 联系表格 7 至 WordPress 用户数据库

    我编写了以下函数 以便在发送联系表单时将其添加到用户数据库字段中 问题是它发送了最终电子邮件 但没有向数据库输入任何内容 因此我一定在某个地方出现错误 任何帮助将不胜感激 add action wpcf7 before send mail
  • 如何向 Spring Security 用户详细信息添加其他详细信息

    我想向用户详细信息添加其他信息 例如用户的 IP 地址 有什么办法可以实现这一点吗 我尝试创建一个新的 CustomSpringUser 类 但问题是如何从 Authentication 对象获取此信息 有没有其他方法来存储经过身份验证的用
  • NSDateFormatter 毫秒错误

    我想创建一个 NSDateFormatter 来解析像这样的日期 2014 05 13 23 31 41 374577 所以 NSDateFormatter formatter NSDateFormatter alloc init form
  • C# 中的带宽限制

    我正在开发一个程序 该程序在后台不断发送数据流 我希望允许用户设置上传和下载限制的上限 我已经阅读了令牌桶 http en wikipedia org wiki Token bucket and 漏桶 http en wikipedia o
  • .NET v4.0 中无法识别的属性“enableSsl”

    我们已经测试运行新系统一段时间了 并将电子邮件创建到文件夹中 这样它们就不会意外发送给客户 现在我们已经打开实时电子邮件发送功能 但我们遇到了发送问题 我正在使用 ActionMailer NET 创建和发送电子邮件的代码如下 我不会包含视
  • 如何修改多个servlet的web.xml

    我只是对如何修改多个 servlet 的 web xml 感到困惑 我有3个servlet来处理3个不同的jsp 但现在只有1个servlet有效 您应该在 web xml 文件中声明并定义类 servlet 如下所示
  • 从 Python 中的“with”块中进行屈服是否安全(以及为什么)?

    协程和资源获取的结合似乎可能会产生一些意想不到的 或不直观的 后果 基本问题是这样的方法是否有效 def coroutine with open path r as fh for line in fh yield line 确实如此 你可以