In the following code I would expect than python is freeing fileinput.input
when I'm return
ing in the middle my loop as it is going out-of-scope. However, when calling again my function fileinput tells me
raise RuntimeError, "input() already active"
Here is my code:
def func(inplace):
for line in fileinput.input(sys.argv[1], inplace=inplace):
[..]
if condition:
return True
[..]
if func(False):
func(True)
I would expect this behavior when using yield
but not when using return.
I'm using Python 2.7.3.
Is there any way to force a reset of fileinput?
EDIT:
When calling fileinput.close()
before returning it works. Why is it not done implicitly?
EDIT 2: Thanks to @MatsLindh
Replacing
for line in fileinput.input(sys.argv[1], inplace=inplace):
with
for line in fileinput.FileInput(sys.argv[1], inplace=inplace):
does what I want, because it returns an object which goes out-of-scope in a defined manner. I assumed that fileinput.input()
does that, but no. It is using a global instance.
So you need to wrap fileinput.input()
in a closing
"context manager" which will **ensure*8 that .close()
is called when you exit the block by using with ...:
:
from contextlib import closing
def func(inplace):
with closing(fileinput.input(sys.argv[1], inplace=inplace)) as finput:
for line in finput:
[..]
if condition:
return True
[..]
Using a context manager on objects that implement the protocol; usually file objects and the like you ensure that cleaned operations are performed on exit of the with
block.
Garbage collection can occur any time; and there are conditions around when objects are freed adn cleaned up. If you want the file object to be closed when you exit the block use
with
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With