2010-11-20 15 views
16

Estoy ejecutando una secuencia de comandos python2.5 en un servidor de Windows 2003 como un servicio. Estoy consiguiendo este error para statments impresión simples:¿por qué recibo IOError: (9, 'Descriptor de archivos incorrectos') error al hacer las declaraciones de impresión?

IOError: (9, 'Bad file descriptor') 

He eliminado todas las declaraciones de impresión, ya que sólo se utilizan con fines de desarrollo, pero no estoy seguro de por qué una sentencia de impresión me causaría ningún Greif. Ejecuté el mismo script no como un servicio sin ningún problema importante. ¿Me pregunto si alguien más tiene alguna idea?

Respuesta

24

No se puede imprimir porque sys.stdout no está disponible cuando no se ejecuta como una sesión de consola.

En lugar de usar las declaraciones print, puede considerar usar el módulo logging para que pueda establecer el nivel de registro y escribir todas las cosas críticas en el registro de eventos del sistema.


Cabe señalar que todavía se puede conseguir que funcione (o silenciosamente ignorar el problema) al hacer algo como esto:

escribir en un archivo por cada secuencia de salida:

import sys 
sys.stdout = open('stdout.txt', 'w') 
sys.stderr = open('stderr.txt', 'w') 

escribir en un solo archivo:

import sys 
sys.stdout = sys.stderr = open('output.txt', 'w') 

O ignorar en silencio todas las declaraciones de impresión:

import sys 
class NullWriter(object): 
    def write(self, value): pass 

sys.stdout = sys.stderr = NullWriter() 
+7

Más específicamente, la primera tres descriptores de archivos (correspondientes a stdin, stdout y stderr) no están disponibles si su programa no se ejecuta en una consola. –

+0

+1 Ignacio Vazquez-Abrams, muy útil. – Wolph

+1

Otra forma de ignorar silenciosamente todas las declaraciones de impresión 'sys.stdout = open (os.devnull, 'w')' –

3

En Python 2.x, este es el comportamiento esperado. En this bug report, Christian Heimes explica que es una decisión de diseño:

I recommend against changing the code so late in the Python 2.7 release cycle. A change in behavior is too confusing. And it's not a bug but a design decision, too. Over five years ago I implement parts of the IO interaction with the operating system for Python 3.0. I deliberately did NOT port modifications to 2.6.

También recomienda una solución alternativa para la obtención de Python 3.x de estilo print() comportamiento en Python 2.7:

from __future__ import print_function 
import sys 
if sys.executable.endswith("pythonw.exe"): 
    sys.stdout = sys.stdout = None 

print("can handle sys.stdout = None just fine.") 
+0

Derrick, ha habido [un poco de disputa sobre esta respuesta] (http://meta.stackoverflow.com/q/318893/). Los usuarios experimentados que trabajan duro para mantener la calidad de la información en este sitio tan alta como sea posible marcaron que contiene solo un enlace a la información fuera del sitio. Tendemos a desalentar este tipo de respuestas, ya que el enlace podría bajar, lo que haría que la respuesta sea inútil. Esta es la razón por la cual se ha votado negativamente, y por qué ha tenido múltiples votos para eliminar el lanzamiento en su contra. Sin embargo, sí veo valor en el enlace que proporcionó, y no creo que eliminar esta respuesta sea la solución adecuada. –

+0

En su lugar, yo y otro usuario hemos editado la información relevante del enlace en su respuesta. Esto debería ayudar a evitar la eliminación pendiente de la respuesta y, posiblemente, obtener más votos favorables. Como eres un nuevo usuario, lamento que hayas tenido una mala experiencia con el sitio. Al publicar respuestas en el futuro, intente recordar que las respuestas correctas son totalmente independientes.Lo mejor que puedo hacer es lo que he hecho aquí y editar la información relevante en la respuesta, incluido el enlace solo como un suplemento. De todos modos, solo quería explicar el negocio divertido. ¡La mejor de las suertes para ti! –

+0

Gracias por la actualización. Incluso aún no estoy seguro de si lo considero un error. La declaración de impresión es la herramienta de depuración de facto, por lo que algo tan simple casi nunca debería fallar en mi opinión. En su edición hay una línea de código: "sys.stdout = sys.stdout = None"; ¿debería ser esto "sys.stdout = sys.stderr = None"? – Derrick

Cuestiones relacionadas