尝试最终用python中的发电机阻止
有人可以向我解释Generator
和的想法,然后在此代码中尝试以外的
:
from contextlib import contextmanager
@contextmanager
def file_open(path):
try:
f_obj = open(path, 'w')
yield f_obj
except OSError:
print("We had an error!")
finally:
print('Closing file')
f_obj.close()
if __name__ == '__main__':
with file_open('test.txt') as fobj:
fobj.write('Testing context managers')
众所周知,无论中的表达式是否正确,都始终执行
。代码>。因此,我认为此代码应该这样起作用:如果我们没有例外,我们打开文件,转到发电机,然后我们最终阻止并从功能返回。但是我不了解Generator
在此代码中的工作方式。我们只使用了一次,这就是为什么我们无法在文件中写所有文本的原因。但是我认为我的想法是不正确的。为什么?
Can someone explain me the idea of generator
and try except
in this code:
from contextlib import contextmanager
@contextmanager
def file_open(path):
try:
f_obj = open(path, 'w')
yield f_obj
except OSError:
print("We had an error!")
finally:
print('Closing file')
f_obj.close()
if __name__ == '__main__':
with file_open('test.txt') as fobj:
fobj.write('Testing context managers')
As I know, finally is always executed regardless of correctness of the expression in try
. So in my opinion this code should work like this: if we haven't exceptions, we open file, go to generator and the we go to finally block and return from the function. But I can't understand how generator
works in this code. We used it only once and that's why we can't write all the text in the file. But I think my thoughts are incorrect. WHy?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,第一,您的实施不正确。即使未能打开,您也会尝试关闭打开的文件对象,这是一个问题。在这种情况下,您需要做的是:
或更简单:
“一般工作中的发电机如何?”我将您推荐您现有问题关于该主题。 两种情况下天生停顿的事实:
@contextlib.contextmanager
decorator repulposes 生成器生成器在很大程度上无关的目的,使用它们在 请求第一个值)tource
(请求每个后续值时)上以实现上下文管理。
contextManager
只是滥用此类课程(实际源代码涵盖边缘案例更为复杂):允许生成器的coroutine元素支持一种更简单的方式来编写简单的上下文管理器。
So, one, your implementation is incorrect. You'll try to close the open file object even if it failed to open, which is a problem. What you need to do in this case is:
or more simply:
To "how do generators in general work?" I'll refer you to the existing question on that topic. This specific case is complicated because using the
@contextlib.contextmanager
decorator repurposes generators for a largely unrelated purpose, using the fact that they innately pause in two cases:yield
(when each subsequent value is requested)to implement context management.
contextmanager
just abuses this to make a class like this (actual source code is rather more complicated to cover edge cases):allowing the coroutine elements of generators to back a simpler way to write simple context managers.