2011-11-09 17 views
7

La función estándar de la biblioteca open funciona tanto como una función:Cómo utilizar Python cierre gestor de contexto

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

o como un gestor de contexto:

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

Estoy tratando de imitar este comportamiento usando contextlib.closing , donde File es mi clase personalizada de E/S de archivo:

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

esto funciona como se esperaba como un gestor de contexto:

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

pero por supuesto si llamo directamente, regrese al closing objeto en lugar de mi objetivo:

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

Así que, ¿Cómo implemento myopen para que funcione como administrador de contexto y devuelve mi objeto File cuando se llama directamente?

ejemplo de trabajo completo en github: https://gist.github.com/1352573

+1

Eso no es para lo que 'closing' es. Usas 'closing' cuando escribes' with' para convertir cualquier objeto con un método 'close' en un administrador de contexto. No lo usas antes de tiempo. El ejemplo [en 'contextlib' docs] (http://docs.python.org/library/contextlib.html#contextlib.closing) parece bastante claro. Si desea poder convertirlo en un administrador de contexto en cualquier momento, entonces la respuesta de Zach es correcta. – agf

Respuesta

13

Lo más fácil es probablemente para implementar los métodos __enter__ y __exit__ mismo. Algo así debe hacerlo:

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

    # context management 
    def __enter__(self): 
     return self 
    def __exit__(self, *exc_info): 
     self.close() 

Sería, por cierto, ser más idiomática para hacer el trabajo de su método de open en su método __init__.

+0

También es posible: simplemente haga el trabajo 'close' en' __exit__' y '' close = __exit__', o viceversa. – agf

+1

+1 para la sugerencia de '__init__' –

Cuestiones relacionadas