Como el hilo ¿Cómo se agrega a un archivo?, la mayoría responde se trata de abrir un archivo y agregarlo, por ejemplo:

def FileSave(content):
    with open(filename, "a") as myfile:
        myfile.write(content)

FileSave("test1 \n")
FileSave("test2 \n")

¿Por qué no extraemos myfile y solo escribimos cuando se invoca FileSave?

global myfile
myfile = open(filename)
def FileSave(content):
    myfile.write(content)

FileSave("test1 \n")
FileSave("test2 \n")

¿Es mejor este último código porque abre el archivo solo una vez y lo escribe varias veces? O bien, no hay diferencia porque lo que hay dentro de python garantizará que el archivo se abra solo una vez, aunque el método open se invoque varias veces.

0
Eugene 10 sep. 2018 a las 06:29

3 respuestas

Realmente depende de las circunstancias, pero aquí hay algunos pensamientos:

Un bloque with garantiza absolutamente que el archivo se cerrará una vez que se salga del bloque. Python no realiza optimizaciones extrañas para agregar archivos.

En general, los globales hacen que su código sea menos modular y, por lo tanto, más difícil de leer y mantener. Se podría pensar que la función original FileSave está intentando evitar los globales, pero está usando el nombre global filename, por lo que también puede usar un archivo global en ese momento, ya que le ahorrará algo E / S por encima.

Una mejor opción sería evitar los globales, o al menos usarlos adecuadamente. Realmente no necesita una función separada para ajustar file.write, pero si representa algo más complejo, aquí hay una sugerencia de diseño:

def save(file, content):
    print(content, file=file)

def my_thing(filename):
    with open(filename, 'a') as f:
        # do some stuff
        save(f, 'test1')
        # do more stuff
        save(f, 'test2')

if __name__ == '__main__':
    my_thing('myfile.txt')

Tenga en cuenta que cuando llama al módulo como un script, un nombre de archivo definido en el ámbito global se pasará a la rutina principal. Sin embargo, dado que la rutina principal no hace referencia a variables globales, puede A) leerla más fácilmente porque es autónoma y B) probarla sin tener que preguntarse cómo alimentar sus entradas sin romper todo lo demás.

Además, al usar print en lugar de file.write, evita tener que gastar nuevas líneas manualmente.

1
Mad Physicist 10 sep. 2018 a las 03:45

El último código puede ser más eficiente, pero el código anterior es más seguro porque asegura que el contenido que cada llamada a FileSave escribe en el archivo se vacía en el sistema de archivos para que otros procesos puedan leer el contenido actualizado, y al cerrar el identificador de archivo con cada llamada usando open como administrador de contexto, también le permite a otros procesos escribir en el archivo (específicamente en Windows).

1
blhsing 10 sep. 2018 a las 03:37

En general, global se debe evitado si es posible.

La razón por la que las personas usan el comando with cuando manejan archivos es porque controla explícitamente el alcance. Una vez que el operador with está listo, el archivo se cierra y la variable del archivo se descarta.

Puede evitar usar el operador with pero debe recordar llamar a myfile.close(). Particularmente si se trata de muchos archivos.

Una forma que evita usar el bloque with que también evita usar global es

 def filesave(f_obj, string):
     f_obj.write(string)

 f = open(filename, 'a')
 filesave(f, "test1\n")
 filesave(f, "test2\n")
 f.close()

Sin embargo, en este punto sería mejor deshacerse de la función y simplemente hacer:

f = open(filename, 'a')
f.write("test1\n")
f.write("test2\n")
f.close()

En ese momento, podría ponerlo fácilmente dentro de un bloque with:

with open(filename, 'a') as f:
    f.write("test1\n")
    f.write("test2\n")

Entonces sí. No hay una razón dura para no hacer lo que estás haciendo. Simplemente no es muy pitónico.

2
m4p85r 10 sep. 2018 a las 03:44