【问题标题】:Looping over resource in python在python中循环资源
【发布时间】:2012-10-05 12:39:00
【问题描述】:

是否有更短的方法来执行以下for-with 组合:

for resource in gen_resources():
    with resource:
        DoWork1(resource)
        .
        .
        DoWorkN(resource)

如果可能的话,我想避免多余的行+缩进。

资源可以是在离开循环迭代时必须完成的任何东西(打开文件、活动对象等)

【问题讨论】:

  • 为什么这很重要?我知道你说过你想避免额外的缩进,但这有什么关系呢?
  • @StevenRumbalski,因为很容易忘记使用with。我迭代的资源不是经典资源,用户很容易忘记调用他们的close() 方法或使用with
  • @Albert 在这种情况下,this answer 确实似乎是最好的,当这个设施被集成到gen_resources() 中时。
  • @Albert:这里的东西对我来说并不重要。您不相信您的用户使用with 或调用close(),但您会相信他们将迭代包装在iterate_with 中?他们不会同样可能忘记使用生成器功能吗?我并不是说您不信任您的用户是错误的,只是建议的解决方案不能解决问题。

标签: python for-loop with-statement


【解决方案1】:

您可以创建一个生成器函数,对每个元素执行with 语句:

def iterate_with(iterable):
    for element in iterable:
        with element:
            yield element

用途:

for resource in iterate_with(gen_resources()):
    DoWork(resource)

我可能仍然会使用您的原始代码,因为代码的读者可能不清楚这里使用了with 语句。

【讨论】:

  • 发电机没有完全耗尽会怎样?
  • @Albert:当生成器被释放时(因为不再有对它的引用),它将关闭并调用当前元素的__exit__。如果您跳出上面显示的for 循环,也会发生这种情况。
【解决方案2】:

只因为你在with中有一个语句:

for resource in gen_resources():
    with resource:  DoWork(resource)

这似乎被普遍反对,但我不知道为什么 - forif 可以做同样的事情,而且非常方便......

【讨论】:

  • 我使用DoWork 进行演示。请参阅已编辑的问题。
  • @Izkata with 必须开始自己的行,否则是语法错误。如果该块中没有任何内容本身具有缩进块,则只能将缩进块制作成一行。
猜你喜欢
  • 2021-11-25
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2010-12-17
  • 2021-10-04
  • 2020-01-21
  • 2017-09-17
相关资源
最近更新 更多