How to use Python closing context manager

Question:

The standard library open function works both as a function:

f = open('file.txt')
print(type(f))
<type 'file'>

or as a context manager:

with open('file.txt') as f:
    print(type(f))
<type 'file'>

I am trying to mimic this behaviour using contextlib.closing, where File is my custom file I/O class:

def my_open(filename):
    f = File(filename)
    f.open()
    return closing(f)

this works as expected as a context manager:

with my_open('file.txt') as f:
    print(type(f))
<class '__main__.File'>

but of course if I call directly, I get back the closing object instead of my object:

f = my_open(filename)
print(type(f))
<class 'contextlib.closing'>

So, how do I implement my_open so that it both works as a context manager and returns my File object when called directly?

Full working example on github:
https://gist.github.com/1352573

Asked By: Andrea Zonca

||

Answers:

The easiest thing is probably to implement the __enter__ and __exit__ methods yourself. Something like this should do it:

class File(object):
   # ... all the methods you already have ...

   # context management
   def __enter__(self):
       return self

   def __exit__(self, *exc_info):
       self.close()

It would, by the way, be more idiomatic to do the work of your open method in your __init__ method.

Answered By: zwol
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.