Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #103961

Re: yield in try/finally case

Newsgroups comp.lang.python
Date 2016-03-03 04:52 -0800
References <84965b86-819b-4924-bca9-e82eed040606@googlegroups.com> <mailman.146.1457007243.20602.python-list@python.org>
Message-ID <de3f3492-063d-469c-8ad2-c93098335a2f@googlegroups.com> (permalink)
Subject Re: yield in try/finally case
From 刘琦帆 <lqf.txx@gmail.com>

Show all headers | View raw


在 2016年3月3日星期四 UTC+8下午8:14:29,Oscar Benjamin写道:
> On 3 March 2016 at 11:52, 刘琦帆 <lqf.txx@gmail.com> wrote:
> >
> > "A yield statement is not allowed in the try clause of a try/finally construct.  The difficulty is that there's no guarantee the generator will ever be resumed, hence no guarantee that the finally block will ever get executed; that's too much a violation of finally's purpose to bear." from https://www.python.org/dev/peps/pep-0255/
> >
> > But, meanwhile, the code showed on that page use yield in a try/finally case.
> > It really puzzles me. Is there anything wrong?
> 
> I think what it means is that you can put a yield in the finally block
> but not the try block so:
> 
> # Not allowed
> def  f():
>     try:
>         yield 1
>     finally:
>         pass
> 
> # Allowed
> def f():
>     try:
>         pass
>     finally:
>         yield 1
> 
> However that information is out of date. The restriction was removed
> in some later Python version. Actually the construct is quite common
> when using generator functions to implement context managers:
> 
> @contextlib.contextmanager
> def replace_stdin(newstdin):
>     oldstdin = sys.stdin
>     try:
>         sys.stdin = newstdin
>         yield
>     finally:
>         sys.stdin = oldstdin
> 
> Although the restriction was removed the problem itself still remains.
> There's no guarantee that a finally block will execute if there is a
> yield in the try block. The same happens if you use a context manager
> around a yield statement: the __exit__ method is not guaranteed to be
> called. One implication of this is that in the following code it is
> not guaranteed that the file will be closed:
> 
> def upperfile(filename):
>     with open(filename) as fin:
>         for line in fin:
>             yield line.upper()
> 
> --
> Oscar


It really nice of you to answer the question. But I am still confused with your last example, is there any case that the file with not be closed? I just run the code and no exception occur.

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

yield in try/finally case 刘琦帆 <lqf.txx@gmail.com> - 2016-03-03 03:52 -0800
  Re: yield in try/finally case Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2016-03-03 12:13 +0000
    Re: yield in try/finally case 刘琦帆 <lqf.txx@gmail.com> - 2016-03-03 04:52 -0800
      Re: yield in try/finally case Peter Otten <__peter__@web.de> - 2016-03-03 14:47 +0100
      Re: yield in try/finally case Random832 <random832@fastmail.com> - 2016-03-03 10:12 -0500
      Re: yield in try/finally case Peter Otten <__peter__@web.de> - 2016-03-03 17:20 +0100
      Re: yield in try/finally case Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2016-03-03 16:24 +0000
  Re: yield in try/finally case Random832 <random832@fastmail.com> - 2016-03-03 10:00 -0500
    Re: yield in try/finally case Steven D'Aprano <steve@pearwood.info> - 2016-03-04 02:57 +1100

csiph-web