python3 - python modulo io
¿Tengo que hacer StringIO.close()? (4)
Algún código:
import cStringIO
def f():
buffer = cStringIO.StringIO()
buffer.write(''something'')
return buffer.getvalue()
La documentation dice:
StringIO.close()
: libera el búfer de memoria. Intentar realizar operaciones adicionales con un objeto StringIO cerrado generará un ValueError.
¿Tengo que hacer buffer.close()
, o sucederá automáticamente cuando el búfer salga del alcance y se recoja la basura?
ACTUALIZAR:
Hice una prueba
import StringIO, weakref
def handler(ref):
print ''Buffer died!''
def f():
buffer = StringIO.StringIO()
ref = weakref.ref(buffer, handler)
buffer.write(''something'')
return buffer.getvalue()
print ''before f()''
f()
print ''after f()''
Resultado:
vic@wic:~/projects$ python test.py
before f()
Buffer died!
after f()
vic@wic:~/projects$
De la fuente:
class StringIO:
...
def close(self):
"""Free the memory buffer.
"""
if not self.closed:
self.closed = True
del self.buf, self.pos
Así que StringIO.close
simplemente libera el búfer de memoria eliminando las referencias a StringIO.buf
y StringIO.pos
. Pero si el self
es recolectado en la basura, sus atributos también serán recolectados, teniendo el mismo efecto que StringIO.close
.
En general, aún es mejor llamar a close()
o usar la instrucción with
, porque puede haber algún comportamiento inesperado en circunstancias especiales. Por ejemplo, el expat- IncrementalParser
parece esperar que se cierre un archivo, o no devolverá el último fragmento de xml analizado hasta que se produzca un tiempo de espera en algunas circunstancias excepcionales.
Pero para with
-statement, que maneja el cierre por usted, tiene que usar la clase StringIO
de los io
Módulos, como se indica en el comentario de Ivc.
Este fue un gran dolor de cabeza en algunas secuencias de comandos de sax-parser heredadas que resolvimos cerrando el StringIO manualmente.
El cierre "fuera de alcance" no funcionó. Acaba de esperar el límite de tiempo de espera.
Terminé usando un bloque de try
para manejarlo.
import cStringIO
def f():
buffer = cStringIO.StringIO()
try:
buffer.write(''something'')
return buffer.getvalue()
finally:
buffer.close()
StringIO.close()
es simplemente una conveniencia para rutinas que toman un tipo de archivo y, finalmente, intentan cerrarlas. No hay necesidad de hacerlo usted mismo.