Mam duży projekt składający się z dostatecznie dużej ilości modułów, każdy drukuje coś na standardowe wyjście. Teraz, gdy projekt się rozrósł, nie ma dużych. od print
sprawozdań Drukowanie partii na std out, która tworzy program znacznie wolniej.
Tak więc chcę teraz zdecydować w czasie wykonywania, czy drukować cokolwiek na standardowe wyjście. Nie mogę wprowadzać zmian w modułach, ponieważ jest ich dużo. (Wiem, że mogę przekierować standardowe wyjście do pliku, ale nawet to jest znacznie powolne).
Więc moje pytanie brzmi: jak przekierować standardowe wyjście do niczego, tj. Jak sprawić, by print
instrukcja nic nie robiła?
# 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.
Obecnie jedynym pomysłem, jaki mam, jest utworzenie klasy, która ma metodę zapisu (która nic nie robi) i przekierowanie standardowego wyjścia do instancji tej klasy.
class DontPrint(object):
def write(*args): pass
dp = DontPrint()
sys.stdout = dp
Czy jest do tego wbudowany mechanizm w Pythonie? A może jest coś lepszego niż to?
źródło
Odpowiedzi:
Wiele platform:
W systemie Windows:
W systemie Linux:
źródło
sys.stdout
i odłóż je później. Na przykładold_stdout = sys.stdout
przed jakimkolwiek innym kodem, a następniesys.stdout = old_stdout
po zakończeniu .os.write(1, b'abc\n')
. Musiszos.dup2()
, aby przekierować na poziomie deskryptora pliku, zobaczstdout_redirected()
sys.__stdout__
do anulowania przekierowania. Więc po prostu to robiszsys.stdout = sys.__stdout__
i nie musisz przechowywać kopii zapasowej.Dobrym sposobem na zrobienie tego jest utworzenie małego procesora kontekstu, w który zawijasz swoje wydruki. Następnie po prostu użyj
with
instrukcji -statement, aby wyciszyć wszystkie wydruki.Python 2:
Python 3.4+:
Python 3.4 ma wbudowany procesor kontekstu, taki jak ten, więc możesz po prostu użyć biblioteki kontekstowej w następujący sposób:
Uruchomienie tego kodu drukuje tylko drugą linię wyniku, a nie pierwszą:
Działa to na wielu platformach (Windows + Linux + Mac OSX) i jest czystsze niż te inne, które odpowiadają imho.
źródło
Jeśli korzystasz z Pythona 3.4 lub nowszego, istnieje proste i bezpieczne rozwiązanie korzystające z biblioteki standardowej:
źródło
with contextlib.redirect_stdout(None)
działa równieżAttributeError: 'NoneType' object has no attribute 'write'
write
metody, która nic nie robi. Zobacz moją odpowiedź poniżej.(przynajmniej w moim systemie) wygląda na to, że zapis do os.devnull jest około 5x szybszy niż zapis do klasy DontPrint, tj.
dał następujący wynik:
źródło
Jeśli pracujesz w środowisku Unix (w tym Linux), możesz przekierować dane wyjściowe do
/dev/null
:A dla Windows:
źródło
nul = myfunc()
?Co powiesz na to:
Używa funkcji modułu contextlib do ukrycia danych wyjściowych dowolnego polecenia, które próbujesz uruchomić, w zależności od wyniku
should_hide_output()
, a następnie przywraca zachowanie wyjścia po wykonaniu tej funkcji.Jeśli chcesz ukryć standardowe wyjście błędów, zaimportuj
redirect_stderr
zcontextlib
i dodaj wiersz z informacjąstack.enter_context(redirect_stderr(null_stream))
.Głównym minusem jest to, że działa to tylko w Pythonie 3.4 i nowszych wersjach.
źródło
redirect_stdout()
analogi we wcześniejszych wersjach Pythona (np. Używająccontextlib.contextmanager
) .Twoja klasa będzie działać dobrze (z wyjątkiem
write()
nazwy metody - należy ją wywołaćwrite()
małymi literami). Tylko pamiętaj, aby zapisać kopięsys.stdout
w innej zmiennej.Jeśli korzystasz z * NIX, możesz to zrobić
sys.stdout = open('/dev/null')
, ale jest to mniej przenośne niż toczenie własnej klasy.źródło
Możesz po prostu kpić.
źródło
Dlaczego tego nie spróbujesz?
źródło
To jest w porządku w
print()
przypadku. Ale może to spowodować błąd, jeśli wywołasz jakąkolwiek metodę sys.stdout, npsys.stdout.write()
.W dokumentach znajduje się uwaga :
źródło
sys.stdout = Null
więc w niektórych przypadkach może to być niebezpieczne.Uzupełnienie odpowiedzi iFreilicht - działa zarówno dla Pythona 2, jak i 3.
źródło