accepting file path or file object?

Peter Otten __peter__ at
Mon Nov 5 14:47:03 CET 2012

andrea crotti wrote:

> 2012/11/5 Peter Otten <__peter__ at>:
>> I sometimes do something like this:

>> @contextmanager
>> def xopen(file=None, mode="r"):
>>     if hasattr(file, "read"):
>>         yield file
       elif file == "-" or file is None: # add file=None handling
>>         if "w" in mode:
>>             yield sys.stdout
>>         else:
>>             yield sys.stdin
>>     else:
>>         with open(file, mode) as f:
>>             yield f

> That's nice thanks, there is still the problem of closing the file
> handle but that's maybe not so important if it gets closed at
> termination anyway..

I think you misunderstood the behaviour of my context manager. The with-
statement (the last two lines) in xopen() implicitly closes files that are 
opened by xopen().

If you pass a file name the file will be closed:

>>> with xopen("") as f: pass
>>> f.closed

However, if you pass an existing file it will not be closed:

>>> import sys
>>> from xopen import xopen
>>> with xopen(sys.stdout) as f: pass
>>> f.closed

That behaviour allows arbitrary nesting of with-statements

fn = ...
with xopen(fn) as f1:
    with xopen(f1) as f2:
        with xopen(f2) as f3:

and the file may only be closed on the outermost level.

More information about the Python-list mailing list