¿Alguien puede decirme cómo puedo hacer esto?

InformationsquelleAutor kaushik | 2010-06-07

12 Comentarios

  1. 76
    with open(filename) as f:
      while True:
        c = f.read(1)
        if not c:
          print "End of file"
          break
        print "Read a character:", c
    • Ya que esta es la lectura de un byte a la vez, no es un error para que no codificaciones ASCII?
    • Preguntas y respuestas son confusas de caracteres y bytes conceptos. Si el archivo está en un solo byte por carácter de codificación como Ascii y muchos otros, entonces sí estás leyendo un solo char por la lectura de un solo byte de tamaño de fragmento, de lo contrario si la codificación requiere más de un solo byte por carácter, entonces usted es sólo la lectura de un solo byte no es un solo personaje.
    • Eso es correcto. Por lo tanto, a menudo lo hago result = open(filename).read() y, a continuación, leer result carácter por carácter.
    • A David Chouinard una pregunta: Este fragmento de código funciona correctamente en Python 3 con archivo con codificación UTF-8. Si usted tiene, por ejemplo, un archivo en Windows-1250 de codificación, sólo el cambio de primera línea para with open(filename, encoding='Windows-1250') as f:
    • Y para agregar a SergO, open(filename, "r") vs open(filename, "rb") pueden resultar en diferentes números de iteraciones (al menos hablando de Python 3). «r» modo podía leer varios bytes para obtener c si golpea el adecuado carácter especial.
  2. 33

    primera vez que abra un archivo:

    with open("filename") as fileobj:
        for line in fileobj:  
           for ch in line: 
               print ch
    • por qué no es esta la respuesta correcta?
    • De acuerdo, esto parece el más Python manera de ir sobre ella. No esta encargarse de la gestión de la no-codificación ASCII así?
    • Una razón que puede leer un archivo de un carácter a un tiempo es que el archivo es demasiado grande para caber en la memoria. Pero la respuesta anterior asume cada línea puede caber en la memoria.
  3. 14

    Me gusta el aceptado respuesta: es sencillo y conseguirá el trabajo hecho. También me gustaría ofrecer una alternativa de implementación:

    def chunks(filename, buffer_size=4096):
        """Reads `filename` in chunks of `buffer_size` bytes and yields each chunk
        until no more characters can be read; the last chunk will most likely have
        less than `buffer_size` bytes.
    
        :param str filename: Path to the file
        :param int buffer_size: Buffer size, in bytes (default is 4096)
        :return: Yields chunks of `buffer_size` size until exhausting the file
        :rtype: str
    
        """
        with open(filename, "rb") as fp:
            chunk = fp.read(buffer_size)
            while chunk:
                yield chunk
                chunk = fp.read(buffer_size)
    
    def chars(filename, buffersize=4096):
        """Yields the contents of file `filename` character-by-character. Warning:
        will only work for encodings where one character is encoded as one byte.
    
        :param str filename: Path to the file
        :param int buffer_size: Buffer size for the underlying chunks,
        in bytes (default is 4096)
        :return: Yields the contents of `filename` character-by-character.
        :rtype: char
    
        """
        for chunk in chunks(filename, buffersize):
            for char in chunk:
                yield char
    
    def main(buffersize, filenames):
        """Reads several files character by character and redirects their contents
        to `/dev/null`.
    
        """
        for filename in filenames:
            with open("/dev/null", "wb") as fp:
                for char in chars(filename, buffersize):
                    fp.write(char)
    
    if __name__ == "__main__":
        # Try reading several files varying the buffer size
        import sys
        buffersize = int(sys.argv[1])
        filenames  = sys.argv[2:]
        sys.exit(main(buffersize, filenames))

    El código que yo sugiero es esencialmente la misma idea que su respuesta: leer un número determinado de bytes del archivo. La diferencia es que primero lee una buena parte de los datos (4006 es un buen valor por defecto para X86, pero es posible que desee para tratar de 1024, o 8192; cualquier múltiplo de su tamaño de la página), y luego que los rendimientos de los personajes en ese pedazo de uno en uno.

    El código presento puede ser más rápido para archivos más grandes. Tomemos, por ejemplo, el texto completo de la Guerra y de la Paz, de Tolstoi. Estos son mis resultados de tiempo (Mac Book Pro con OS X 10.7.4; so.py es el nombre que se daba a el código que he pegado):

    $ time python so.py 1 2600.txt.utf-8
    python so.py 1 2600.txt.utf-8  3.79s user 0.01s system 99% cpu 3.808 total
    $ time python so.py 4096 2600.txt.utf-8
    python so.py 4096 2600.txt.utf-8  1.31s user 0.01s system 99% cpu 1.318 total

    Ahora: no tome el tamaño de búfer en 4096 como una verdad universal; mira los resultados que obtengo de diferentes tamaños (tamaño de búfer (bytes) vs pared de tiempo (seg)):

       2 2.726 
       4 1.948 
       8 1.693 
      16 1.534 
      32 1.525 
      64 1.398 
     128 1.432 
     256 1.377 
     512 1.347 
    1024 1.442 
    2048 1.316 
    4096 1.318 

    Como usted puede ver, usted puede empezar a ver ganancias anteriores (y mis horarios son probablemente muy inexacta); el tamaño del búfer es un trade-off entre la memoria y el rendimiento. El valor por defecto de 4096 es sólo una opción razonable, pero, como siempre, medir primero.

  4. 8

    El propio Python puede ayudar con esto, en modo interactivo:

    >>> help(file.read)
    Help on method_descriptor:
    
    read(...)
        read([size]) -> read at most size bytes, returned as a string.
    
        If the size argument is negative or omitted, read until EOF is reached.
        Notice that when in non-blocking mode, less data than what was requested
        may be returned, even if no size parameter was given.
    • Estoy de acuerdo con el sentimiento, pero tal vez este es el mejor como un comentario a la OP?
    • Podría ser, pero yo creo que el texto sería desordenado en un comentario.
  5. 0
    f = open('hi.txt', 'w')
    f.write('0123456789abcdef')
    f.close()
    f = open('hej.txt', 'r')
    f.seek(12)
    print f.read(1) # This will read just "c"
    • Bienvenido a Stackoverflow! Usted debe elaborar – ¿por qué es esto una respuesta?
  6. 0

    Esto también funciona:

    with open("filename") as fileObj:
        for line in fileObj:  
            for ch in line:
                print(ch)

    Que pasa a través de cada línea en el archivo y todos los caracteres en cada línea.

  7. 0

    Para hacer un suplemento,
    si usted está leyendo el archivo que contiene una línea que es vvvvery enorme, que podría romper su memoria, usted podría considerar la posibilidad de leerlos en un buffer, entonces el rendimiento de cada char

    def read_char(inputfile, buffersize=10240):
        with open(inputfile, 'r') as f:
            while True:
                buf = f.read(buffersize)
                if not buf:
                    break
                for char in buf:
                    yield char
            yield '' #handle the scene that the file is empty
    
    if __name__ == "__main__":
        for word in read_char('./very_large_file.txt'):
            process(char)
  8. 0
    #reading out the file at once in a list and then printing one-by-one
    f=open('file.txt')
    for i in list(f.read()):
        print(i)
    • Mientras que esto puede responder a los autores en cuestión, carece de algunas de explicar las palabras y los enlaces a la documentación. Raw fragmentos de código no son muy útiles sin algunas frases a su alrededor. Usted también puede encontrar cómo escribir una buena respuesta muy útil. Por favor, edita tu respuesta.
    • Usted no necesita el elenco a la lista.

Dejar respuesta

Please enter your comment!
Please enter your name here