8
votes

Suppression de la sortie du module appelant à l'extérieur de la bibliothèque

J'ai un problème gênant lors de l'utilisation de la bibliothèque d'apprentissage de la machine pyml . Pyml utilise libsvm pour former le classificateur SVM. Le problème est que Libsvm génère un peu de texte à la sortie standard. Mais parce que c'est à l'extérieur de Python, je ne peux pas l'intercepter. J'ai essayé d'utiliser des méthodes décrites dans Problème Silence the stdout d'une fonction en Python sans détruire sys.s.s.s.s.stdout et restaurer chaque appel de fonction mais aucune de ces aides.

Y a-t-il quelque chose à faire cela. La modification de Pyml n'est pas une option.


2 commentaires

Avez-vous vérifié cela, peut-être qu'il écrit dans sys.stderr et non sys.stsdout !!!


Connexes: Rediriger Stdout à un fichier de Python? - Le fichier est os.devnull ce cas.


4 Réponses :


10
votes

Ouvrir / dev / null pour écrire, utiliser os.dup () Pour copier stdout et utilisez os.dup2 () à Copiez votre open / dev / null sur stdout. Utilisez os.dup2 () pour copier votre stdout copié à la vraie stdout après. XXX


4 commentaires

'olfstdout = OS.DUP (SYS.STDOUT) "jette un entier" un entier est requis "


Syts.stsdout.fileno () et Devnull.fileno () sont nécessaires et cela fonctionne après cela, merci !!


Ne devriez-vous pas fermer Devnull à la fin en utilisant devnull.close () ou ouvrez-le à l'aide du avec Déclaration?


Reid, votre réponse ne fonctionne toujours pas pour moi. J'avais besoin d'un os.fsync (devnull.fileno ()) Avant la dernière DUP2 pour déboguer, essayez importer pybullet comme pb comme la chose que vous voulez faire taire :)



0
votes

J'ai eu le même problème et je l'ai réparé comme ça: xxx


3 commentaires

Cela fonctionnera si svm_predict est la sortie provient de Python mais pas s'il provient d'une bibliothèque partagée que les appels Python, que je crois, c'est ce que l'OP avait demandé.


Pour moi, cela a fonctionné en utilisant les liaisons Python de libsvm . Je suppose que pour Pyml La situation est similaire. STDOUT est une propriété de processus, c'est-à-dire que mon enveloppement (ainsi que la solution de Ignacio) fonctionne parfaitement tant que la fonctionnalité externe n'est pas utilisée via des sous-processus. Seulement échouerait si quelqu'un ouvre / dev / stdout pour écrire la sortie à.


Ce qui est exactement ce que font la plupart des bibliothèques partagées, c'est pourquoi cette solution ne fonctionnera pas pour la plupart des gens. La solution ci-dessus va être plus proche de ce que les besoins demandeurs ont besoin.



3
votes

Dave Smith a donné une réponse merveilleuse à celle de son Blog . Fondamentalement, il enveloppe la réponse de Ignacio joliment:

from contextlib import contextmanager
import os
import sys

@contextmanager
def suppress_stdout():
    with open(os.devnull, "w") as devnull:
        old_stdout = sys.stdout
        sys.stdout = devnull
        try:  
            yield
        finally:
            sys.stdout = old_stdout


3 commentaires

Ces solutions ne peuvent supprimer que la sortie produite dans Python.


Probablement, oui. De plus, j'ai constaté que cette solution ne supprima pas de la sortie Python, par exemple la barre de progression TQDM parvient à imprimer à STDOUT même lorsque dans ce contexte, je ne sais pas pourquoi. Néanmoins, j'ai trouvé que pour la plupart des cas de Python, cela fonctionne.


TQDM Progressbar est imprimé sur STDRERR par défaillance de la Suppression, vous devez également rediriger sys.stsderr



0
votes

J'ai eu un problème similaire avec l'initialisation Portudio / Pyaudio. J'ai commencé avec la réponse de Reid, qui a fonctionné. Bien que je devais rediriger Sterrr à la place. Ainsi, voici une version à plate-forme mise à jour mise à jour qui redirige à la fois:

import sys, os

# hide diagnostic output
with open(os.devnull, 'w') as devnull:
    # suppress stdout
    orig_stdout_fno = os.dup(sys.stdout.fileno())
    os.dup2(devnull.fileno(), 1)
    # suppress stderr
    orig_stderr_fno = os.dup(sys.stderr.fileno())
    os.dup2(devnull.fileno(), 2)

    print('*** stdout should be hidden!  ****')
    print('*** stderr should be too!  ****',
          file=sys.stderr)

    os.dup2(orig_stdout_fno, 1)  # restore stdout
    os.dup2(orig_stderr_fno, 2)  # restore stderr

print('done.')


0 commentaires