2010-09-21 17 views
45

En Ruby puede leer desde un archivo usando s = File.read(filename). El más corto y más claro que conozco en Python esLa forma más fácil de leer/escribir el contenido de un archivo en Python

with file(filename) as f: 
    s = f.read() 

¿Hay alguna otra manera de hacerlo que lo hace aún más corta (preferiblemente una línea) y más legible?

Nota: inicialmente formulé la pregunta como "hacer esto en una sola línea de código". Como señala S.Lott, más corto no necesariamente significa más legible. Así que reformulé mi pregunta solo para aclarar a qué me refería. Creo que el código de Ruby es mejor y más legible no necesariamente porque es una línea versus dos (aunque eso también importa), sino también porque es un método de clase en comparación con un método de instancia, que no plantea dudas sobre quién cierra el archivo. cómo asegurarse de que se cierra incluso si se produce una excepción, etc. Como se señala en las respuestas a continuación, puede confiar en que el GC cerrará su archivo (lo que hace que esto sea único), pero eso empeora el código incluso aunque es más corto. No solo por ser inservible, sino por hacerlo poco claro.

+6

Crear su propia función . Entonces puedes usarlo para obtener los contenidos. La llamada sería una línea. –

+0

@Felix Hehe, claro. Estaba buscando una forma de hacerlo usando la biblioteca estándar. :) – ibz

+1

Simplemente curioso, ¿la declaración de Ruby cierra el archivo también? – dheerosaur

Respuesta

6

Si usted está abierto a la utilización de las bibliotecas, intente instalar forked-path (ya sea con o easy_install PIP).

entonces usted puede hacer:

from path import path 
s = path(filename).bytes() 

Esta biblioteca es bastante nuevo, pero es un tenedor de una biblioteca que ha estado flotando alrededor de Python desde hace años y se ha utilizado un poco. Desde que encontré esta biblioteca hace años, rara vez uso os.path o open().

+0

Parece una buena biblioteca. No lo instalaré solo para esto, pero lo tendré en cuenta. – ibz

+3

¿por qué no file (filename) .read()? – coyotte508

+0

No entiendo por qué esta fue la respuesta aceptada ya que es un truco total. – nikolay

35

Esto es igual que el anterior pero no maneja errores:

s = open(filename, 'r').read() 
+12

No realmente, el suyo deja el archivo abierto. – ibz

+1

La implementación de CPython cierra el archivo cuando el recuento de referencias va a cero, pero es un detalle de implementación en el que no se debe confiar. –

+0

Esto maneja errores; se lanzará una excepción como de costumbre. Esto no * "deja el archivo abierto", pero lo que puede hacer es causar que el archivo sea * retrasado * dependiendo de la implementación del GC. Eso puede ser un problema (bloqueo en Windows y, por ejemplo, límites de FD si se repiten muchos archivos), pero eso es muy diferente de dejar el archivo abierto (por ejemplo, filtrar el archivo). –

11
contents = open(filename).read() 
+2

¿Y cuándo cierras el archivo? – ibz

+1

@ionut bizau - Cuando el retorno de 'open (...)' es basura recolectada, creo. Que alguien me corrija si me equivoco. – detly

+1

Esta es la forma más corta de hacerlo. No sé por qué no tiene votos. –

80
with open('x.py') as f: s = f.read() 

*** *** muecas

+0

Votó la apuesta por intentar ser gracioso. Sin embargo, no marcó como aceptado. :)) – ibz

+1

awwwwwwwwww; ^) –

+4

¿Qué pasa con esta respuesta? ¿no recomendado? – balki

4

lenta, feo, plataforma específica, pero ... de una sola línea ;-)

import subprocess 

contents = subprocess.Popen('cat %s' % filename, shell = True, stdout = subprocess.PIPE).communicate()[0] 
+2

aaaaaaaaaaargh! (exceso de 'a para cumplir con el límite mínimo de char) –

+5

Ciertamente coincide con el espíritu de la pregunta ... el uso perverso de Python para que se asemeje a Bash no es peor que hacer que se parezca a Ruby o Perl. – detly

-1
contents = open(filename) 

Esto le da generador, así que debe guardar en algún lugar los valores embargo, o

contents = [line for line in open(filename)] 

Este es el que salva a la lista de cerca explícito no es entonces posible (al menos con mis conocimientos de Python).

+1

¿por qué no hay necesidad de cerrar? – aaronasterling

+1

y con contents = '' .join (línea para la línea en abierto (nombre de archivo)) tiene el contenido original del archivo ... – eumiro

+0

Usar un archivo como un iterador no * cierra * el archivo deterministicamente (como 'con') . No puede, porque una vez que finaliza la iteración, sigue siendo válido buscar el archivo y comenzar a leer nuevamente, lo que no funcionaría si la iteración cerró el archivo. –

6

Esto no es Perl; no desea forzar el ajuste de múltiples líneas de código en una sola línea. Escribe una función, luego llamar a la función toma una línea de código.

def read_file(fn): 
    """ 
    >>> import os 
    >>> fn = "/tmp/testfile.%i" % os.getpid() 
    >>> open(fn, "w+").write("testing") 
    >>> read_file(fn) 
    'testing' 
    >>> os.unlink(fn) 
    >>> read_file("/nonexistant") 
    Traceback (most recent call last): 
     ... 
    IOError: [Errno 2] No such file or directory: '/nonexistant' 
    """ 
    with open(fn) as f: 
     return f.read() 

if __name__ == "__main__": 
    import doctest 
    doctest.testmod() 
1

Utilice pathlib.

Python 3.5 y superiores:

from pathlib import Path 
contents = Path(file_path).read_text() 

Para versiones inferiores de Python utilizan pathlib2:

$ pip install pathlib2 

Entonces

from pathlib2 import Path 
contents = Path(file_path).read_text() 

escritura es igual de fácil:

Path(file_path).write_text('my text') 
Cuestiones relacionadas