2010-11-20 3 views
16

J'utilise un script python2.5 sur un serveur Windows 2003 en tant que service. Je reçois cette erreur pour statments impression simples:Pourquoi est-ce que je reçois IOError: (9, erreur 'Descripteur de fichier incorrect') lors de la création des instructions d'impression?

IOError: (9, 'Bad file descriptor') 

J'ai supprimé toutes les déclarations d'impression parce qu'ils ont été utilisés uniquement à des fins de développement, mais je ne suis pas sûr pourquoi une déclaration d'impression me causer de Greif. J'ai couru le même script pas comme un service sans problèmes majeurs. Je me demande juste si quelqu'un d'autre a un aperçu?

Répondre

24

Vous ne pouvez pas imprimer car sys.stdout n'est pas disponible lorsqu'il n'est pas exécuté en tant que session de console. Au lieu d'utiliser les instructions print, vous pouvez utiliser le module logging pour définir le niveau de journalisation et écrire toutes les informations importantes dans le journal des événements système.


Il convient de noter que vous pouvez toujours le faire fonctionner (ou ignorer en silence le problème) en faisant quelque chose comme ceci:

Pour écrire dans un fichier par flux de sortie:

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

pour écrire à un seul fichier:

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

Ou ignorer silencieusement toutes les déclarations d'impression:

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

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

Plus précisément, le premier trois descripteurs de fichiers (correspondant à stdin, stdout et stderr) ne sont pas disponibles si votre programme ne s'exécute pas dans une console. –

+0

+1 Ignacio Vazquez-Abrams, très utile. – Wolph

+1

Une autre façon d'ignorer silencieusement toutes les instructions d'impression 'sys.stdout = open (os.devnull, 'w')' –

3

Dans Python 2.x, il s'agit du comportement attendu. En this bug report, Christian Heimes explique qu'il est une décision de conception:

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.

Il recommande également une solution pour obtenir le comportement Python 3.x style print() 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, il y a eu [un peu de controverse sur cette réponse] (http://meta.stackoverflow.com/q/318893/). Les utilisateurs expérimentés qui travaillent dur pour maintenir la qualité des informations sur ce site aussi haut que possible l'ont signalé comme contenant uniquement un lien vers des informations hors site. Nous avons tendance à décourager de tels types de réponses, car le lien pourrait diminuer, ce qui rendrait la réponse inutile. C'est pourquoi il a été downvoted, et pourquoi il a eu plusieurs votes à supprimer contre lui. Cependant, je vois de la valeur dans le lien que vous avez fourni, et je ne pense pas que la suppression de cette réponse soit la solution appropriée. –

+0

Au lieu de cela, moi et un autre utilisateur avons modifié les informations pertinentes du lien dans votre réponse. Cela devrait aider à éviter la suppression en attente de la réponse, et peut-être vous gagner quelques upvotes plus. Comme vous êtes un nouvel utilisateur, je suis désolé que vous ayez eu une mauvaise expérience avec le site. Lorsque vous postez des réponses à l'avenir, essayez de garder à l'esprit que les bonnes réponses sont entièrement autonomes.La meilleure chose à faire est ce que j'ai fait ici, et modifier les informations pertinentes dans la réponse, y compris le lien seulement comme un supplément. De toute façon, je voulais juste expliquer le business marrant. Bonne chance à vous! –

+0

Merci pour la mise à jour. Même moi, je suis toujours indécis si je considère que c'est un bug. La déclaration d'impression est l'outil de débogage de facto de sorte que quelque chose de si simple ne devrait presque jamais échouer à mon avis. Dans votre édition, il y a une ligne de code: "sys.stdout = sys.stdout = None"; devrait-il être "sys.stdout = sys.stderr = None"? – Derrick

Questions connexes