tutorial lenguaje instalar descargar python

lenguaje - Python 3 TypeError: debe ser str, no bytes con sys.stdout.write()



python tutorial (2)

Estaba buscando una forma de ejecutar un proceso externo desde el script python e imprimir sus mensajes estándar durante la ejecución.
El siguiente código funciona, pero no imprime salida estándar durante el tiempo de ejecución. Cuando sale recibo el siguiente error:

sys.stdout.write (nextline) TypeError: debe ser str, no bytes

p = subprocess.Popen(["demo.exe"],stdout = subprocess.PIPE, stderr= subprocess.PIPE) # Poll process for new output until finished while True: nextline = p.stdout.readline() if nextline == '''' and p.poll() != None: break sys.stdout.write(nextline) sys.stdout.flush() output = p.communicate()[0] exitCode = p.returncode

Estoy usando python 3.3.2


Python 3 maneja cadenas un poco diferentes. Originalmente solo había un tipo para cadenas: str . Cuando el Unicode ganó tracción en los años 90, se agregó el nuevo tipo unicode para manejar Unicode sin romper el código preexistente 1 . Esto es efectivamente lo mismo que str pero con soporte multibyte.

En Python 3 hay dos tipos diferentes:

  • El tipo de bytes . Esto es solo una secuencia de bytes, Python no sabe nada sobre cómo interpretar esto como personajes.
  • El tipo str . Esta es también una secuencia de bytes, pero Python sabe cómo interpretar esos bytes como caracteres .
  • El tipo de unicode separado se eliminó. str ahora es compatible con Unicode.

En Python 2 asumir implícitamente una codificación podría causar muchos problemas; podrías terminar usando la codificación incorrecta, o los datos pueden no tener una codificación en absoluto (por ejemplo, es una imagen PNG).
Explicar explícitamente a Python qué codificación usar (o explícitamente diciéndole que adivine) a menudo es mucho mejor y mucho más en línea con la "filosofía de Python" de " explícito es mejor que implícito ".

Este cambio es incompatible con Python 2 ya que muchos valores de retorno han cambiado, lo que genera problemas sutiles como este; es probable que sea la razón principal por la cual la adopción de Python 3 ha sido tan lenta. Como Python no tiene tipado estático 2 , es imposible cambiarlo automáticamente con un script (como el 2to3 incluido).

  • Puede convertir str a bytes con bytes(''h€llo'', ''utf-8'') ; esto debería producir b''H/xe2/x82/xacllo'' . Tenga en cuenta cómo un personaje se convirtió a tres bytes.
  • Puede convertir bytes en str con b''H/xe2/x82/xacllo''.decode(''utf-8'') .

Por supuesto, es posible que UTF-8 no sea el juego de caracteres correcto en su caso, así que asegúrese de usar el correcto.

En su pieza específica de código, nextline es de tipo bytes , no str , leyendo stdout y stdin del subprocess cambiado en Python 3 de str a bytes . Esto se debe a que Python no puede estar seguro de qué codificación utiliza. Probablemente use lo mismo que sys.stdin.encoding (la codificación de su sistema), pero no puede estar seguro.

Debes reemplazar:

sys.stdout.write(nextline)

con:

sys.stdout.write(nextline.decode(''utf-8''))

o tal vez:

sys.stdout.write(nextline.decode(sys.stdout.encoding))

También deberá modificar if nextline == '''' a if nextline == b'''' desde:

>>> '''' == b'''' False

También vea el Python 3 ChangeLog , PEP 358 y PEP 3112 .

1 Hay algunos trucos ingeniosos que puede hacer con ASCII que no puede hacer con conjuntos de caracteres multibyte; el ejemplo más famoso es el "xor con espacio para cambiar de caja" (por ejemplo, chr(ord(''a'') ^ ord('' '')) == ''A'' ) y "establecer 6to bit para hacer un caracter de control" (ej. ord(''/t'') + ord(''@'') == ord(''I'') ). ASCII fue diseñado en un momento en que la manipulación de bits individuales era una operación con un impacto de rendimiento no despreciable.

2 Sí, puede usar anotaciones de función, pero es una función comparativamente nueva y poco utilizada.


Si bien la respuesta aceptada funcionará correctamente si los bytes que tiene de su subproceso están codificados mediante sys.stdout.encoding (o una codificación compatible, como leer desde una herramienta que emite ASCII y su stdout usa UTF-8), la forma correcta de escribir bytes arbitrarios para stdout es:

sys.stdout.buffer.write(some_bytes_object)

Esto solo generará los bytes tal como están, sin tratar de tratarlos como texto en alguna codificación.