Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is fileinput.input object not lost when going out-of-scope?

Tags:

python

scope

In the following code I would expect than python is freeing fileinput.input when I'm returning 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.

like image 373
Patrick B. Avatar asked Jun 19 '15 09:06

Patrick B.


1 Answers

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.

like image 164
James Mills Avatar answered Oct 05 '22 17:10

James Mills