Python open () anexa y lee, file.read () devuelve una cadena vacía

Notó un comportamiento extraño al intentar llamar a read() en un archivo abierto en modo a+ (Python 3.4.1)

Como se ve aquí
Modo de archivo para crear + leer + añadir + binario
Es posible abrir un archivo en modo de lectura / adición supuestamente .

sin embargo
Este código:

 with open("hgrc", "a+") as hgrc: contents=hgrc.read() 

devuelve contents={str}'' . Lo cual es inesperado basado en la respuesta publicada anteriormente.
Ahora, el siguiente código

 with open("hgrc", "r+") as hgrc: contents=hgrc.read() 

devuelve contents={str}'contents of hgrc.....' , que se espera, pero no nos da la opción de adjuntar al archivo.

Según las especificaciones.

https://docs.python.org/2/library/functions.html#open

Modes 'r+', 'w+' and 'a+' open the file for updating (reading and writing); note that 'w+' truncates the file. Append 'b' to the mode to open the file note that 'w+' truncates the file. Append 'b' to the mode to open the file in binary mode, on systems that differentiate between binary and text files; on systems that don't have this distinction, adding the 'b' has no in binary mode, on systems that differentiate between binary and text files; on systems that don't have this distinction, adding the 'b' has no files; on systems that don't have this distinction, adding the 'b' has no effect.

Lo que significa
Cuando abrimos un archivo en a+ modo a+ , deberíamos poder llamar a read() y recuperar el contenido del archivo, ¿correcto? ¿Pensamientos? Opiniones? Etc ??

a+ abre el archivo al final para adjuntarlo. .seek(0) llamar a .seek(0) en él si luego desea leer su contenido, pero en ese momento también puede usar r+ , porque eso abre el archivo al principio.

Este es un problema de Python 2 vs. Python 3

open() con a+ comporta de manera diferente en las dos versiones de Python. (Nota: revela que está usando Python 3.4.1 , ¡pero está citando la documentación de Python 2 !)

(De hecho, el comportamiento que está buscando (en ” Qué significa “) funciona según lo previsto con Python 2. Creo que cambiaron el comportamiento, porque “anexar” significa “puntero de archivo al final del archivo” para muchas personas).


Probemos esto con Python3 …

 $ python3 Python 3.4.3 (default, Jul 28 2015, 18:20:59) [GCC 4.8.4] on linux Type "help", "copyright", "credits" or "license" for more information. >>> lic = open('LICENSE', 'a+') >>> lic.read() '' >>> # Hmmm, no content? EOF, obviously. Let's reset the file pointer ... >>> lic.seek(0) 0 >>> lic.read() 'Apache License\nVersion 2.0, January 2004\n...' 

Lo mismo con Python2 …

 $ python Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> lic = open('LICENSE', 'a+') >>> lic.read() 'Apache License\nVersion 2.0, January 2004\n...' >>> lic.seek(0) >>> lic.read() 'Apache License\nVersion 2.0, January 2004\n...' 

Conclusión: está seguro utilizando la seek(0) siempre después de abrir un archivo con a+ , independientemente de la versión de Python que utilice. Esto parece ser específico para el modo a a+ .


¿Por qué una llamada al sistema se comporta de manera diferente en dos versiones de Python?

Uno pensaría que la manipulación de archivos es una llamada al sistema, por lo tanto, es manejada por el sistema operativo. Esto es diferente con Python, ya que se ve de acuerdo con la documentación de Python :

Nota: Python no depende de la noción de archivos de texto del sistema operativo subyacente; Todo el procesamiento lo realiza Python, y por lo tanto es independiente de la plataforma.

Por cierto, este comportamiento ha sido reportado como un error en el rastreador de errores de Python.