J'ai un grand projet constitué d'un nombre suffisamment grand de modules, chacun imprimant quelque chose sur la sortie standard. Maintenant que le projet a pris de l'ampleur, il y en a beaucoup. of print
instructions imprimant beaucoup sur le std out, ce qui a considérablement ralenti le programme.
Donc, je veux maintenant décider à runtime s'il faut ou non imprimer quoi que ce soit sur la sortie standard. Je ne peux pas modifier les modules car ils sont nombreux. (Je sais que je peux rediriger la sortie standard vers un fichier, mais même cela est considérablement lent.)
Ma question est donc: comment rediriger la sortie standard vers rien, c’est-à-dire comment faire en sorte que la déclaration print
ne fasse rien?
# I want to do something like this.
sys.stdout = None # this obviously will give an error as Nonetype object does not have any write method.
Actuellement, la seule idée que j'ai est de faire une classe qui a une méthode d'écriture (qui ne fait rien) et de rediriger la sortie standard vers une instance de cette classe.
class DontPrint(object):
def write(*args): pass
dp = DontPrint()
sys.stdout = dp
Existe-t-il un mécanisme intégré dans python pour cela? Ou y a-t-il quelque chose de mieux que cela?
Multiplate-forme:
import os
import sys
f = open(os.devnull, 'w')
sys.stdout = f
Sous Windows:
f = open('nul', 'w')
sys.stdout = f
Sous Linux:
f = open('/dev/null', 'w')
sys.stdout = f
Une bonne façon de faire est de créer un petit processeur de contexte dans lequel vous emballez vos impressions. Vous utilisez alors simplement une instruction with
- pour faire taire toutes les sorties.
import os
import sys
from contextlib import contextmanager
@contextmanager
def silence_stdout():
new_target = open(os.devnull, "w")
old_target = sys.stdout
sys.stdout = new_target
try:
yield new_target
finally:
sys.stdout = old_target
with silence_stdout():
print("will not print")
print("this will print")
L'exécution de ce code n'imprime que la deuxième ligne de sortie, pas la première:
$ python test.py
this will print
Cela fonctionne sur plusieurs plates-formes (Windows + Linux + Mac OSX), et est plus propre que les autres réponses à mon humble avis.
Si vous êtes dans python 3.4 ou supérieur, il existe une solution simple et sûre qui utilise la bibliothèque standard:
import contextlib
import os
with contextlib.redirect_stdout(None):
print("This won't print!")
(du moins sur mon système), il apparaît que l'écriture sur os.devnull est environ 5 fois plus rapide que l'écriture sur une classe DontPrint, c'est-à-dire.
#!/usr/bin/python
import os
import sys
import datetime
ITER = 10000000
def printlots(out, it, st="abcdefghijklmnopqrstuvwxyz1234567890"):
temp = sys.stdout
sys.stdout = out
i = 0
start_t = datetime.datetime.now()
while i < it:
print st
i = i+1
end_t = datetime.datetime.now()
sys.stdout = temp
print out, "\n took", end_t - start_t, "for", it, "iterations"
class devnull():
def write(*args):
pass
printlots(open(os.devnull, 'wb'), ITER)
printlots(devnull(), ITER)
a donné la sortie suivante:
<open file '/dev/null', mode 'wb' at 0x7f2b747044b0>
took 0:00:02.074853 for 10000000 iterations
<__main__.devnull instance at 0x7f2b746bae18>
took 0:00:09.933056 for 10000000 iterations
Si vous êtes dans un environnement Unix (Linux inclus), vous pouvez rediriger la sortie vers /dev/null
:
python myprogram.py > /dev/null
Et pour Windows:
python myprogram.py > nul
Que dis-tu de ça:
from contextlib import ExitStack, redirect_stdout
import os
with ExitStack() as stack:
if should_hide_output():
null_stream = open(os.devnull, "w")
stack.enter_context(null_stream)
stack.enter_context(redirect_stdout(null_stream))
noisy_function()
Ceci utilise les fonctionnalités du module contextlib pour masquer la sortie de la commande que vous essayez d'exécuter, en fonction du résultat de should_hide_output()
, puis restaure le comportement de sortie après cette fonction. est fait courir.
Si vous souhaitez masquer la sortie d'erreur standard, importez redirect_stderr
De contextlib
et ajoutez une ligne disant stack.enter_context(redirect_stderr(null_stream))
.
Le principal inconvénient est que cela ne fonctionne que dans Python 3.4 et versions ultérieures.
Votre classe fonctionnera parfaitement (à l'exception du nom de la méthode write()
- elle doit s'appeler write()
, en minuscule). Assurez-vous simplement de sauvegarder une copie de sys.stdout
Dans une autre variable.
Si vous êtes sur un * NIX, vous pouvez faire sys.stdout = open('/dev/null')
, mais c'est moins portable que de rouler votre propre classe.
Vous pouvez simplement vous moquer de lui.
import mock
sys.stdout = mock.MagicMock()