¿Cómo usar NamedTemporaryFile (y cuándo está cerrado?)

Estoy tratando de escribir una serie de funciones que escriben en un archivo temporal, y luego hace cosas con el archivo escrito. Estoy tratando de entender cómo se trata el archivo.

Lo que me gustaría hacer en el resumen es:

def create_function(inputs): # create temp file, write some contents def function1(file): # do some stuff with temp file def function2(file): # do some other stuff with temp file 

Para que yo pueda hacer algo como:

 my_file = create_function(my_inputs) function1(my_file) function2(my_file) 

Así que aquí está lo que realmente he hecho:

 def db_cds_to_fna(collection, open_file): """ This pulls data from a mongoDB and writes it to a temporary file - just writing an arbitrary string doesn't alter my question (I'm pretty sure) """ for record in db[collection].find({"type": "CDS"}): open_file.write(">{}|{}|{}\n{}\n".format( collection, record["_id"], record["annotation"], record["dna_seq"] ) ) return open_file.name def check_file(open_file): lines = 0 for line in open_file: if lines < 5: print line lines += 1 else: break 

Con este código, si ejecuto lo siguiente:

 from tempfile import NamedTemporaryFile tmp_file = NamedTemporaryFile() tmp_fna = db_cds_to_fna('test_collection', tmp_file) check_file(tmp_file) 

Este código se ejecuta, pero en realidad no imprime nada. Pero el archivo está claramente allí y escrito, porque si ejecuto print Popen(['head', tmp_fna], stdout=PIPE)[0] , obtengo el inicio esperado del archivo. O, si cambio check_file() para aceptar el tmp_file.name y lo hago with open(tmp_file.name, 'r')... dentro de la función, funciona.

Entonces, la pregunta 1 es: ¿por qué puedo escribir en el tmp_file , pero no puedo leerlo desde una función diferente sin volver a abrirlo?

Ahora, lo que realmente me gustaría hacer es tener el tmp_file = NamedTemporaryFile() dentro de la función db_cds_to_fna() , pero cuando bash esto y ejecuto:

 tmp_fna = db_cds_to_fna('test_collection') check_file(tmp_file) 

Me sale un error No such file or folder

Entonces, la pregunta 2 es: ¿hay alguna manera de mantener el archivo temporal alrededor para que otra función lo use? Sé cómo escribir un archivo en una ruta específica y luego borrarlo, pero sospecho que hay una forma integrada de hacerlo y me gustaría aprender.

Estás escribiendo en el archivo, pero luego intentas leerlo desde el final de tus escrituras. Agregue una seek antes de comenzar a leer, para volver al principio del archivo:

 def check_file(open_file): lines = 0 open_file.seek(0) for line in open_file: if lines < 5: print line lines += 1 else: break 

Para su segunda pregunta, tenga en cuenta que NamedTemporaryFile funciona como TemporaryFile en eso:

Se destruirá tan pronto como se cierre (incluido un cierre implícito cuando el objeto se recolecta como basura).

Si abre el archivo en una función y luego regresa, el archivo queda fuera del scope y se cerrará y se recogerá la basura. Deberá mantener viva una referencia al objeto de archivo para evitar que se recopile. Puede hacerlo devolviendo el objeto de archivo desde la función (y asegurándose de asignarlo a algo). Aquí hay un ejemplo trivial:

 def mycreate(): return NamedTemporaryFile() def mywrite(f, i): f.write(i) def myread(f): f.seek(0) return f.read() f = mycreate() # 'f' is now a reference to the file created in the function, # which will keep it from being garbage collected mywrite(f, b'Hi') myread(f)