Istnieje kilka sposobów pisania na stderr:
# Note: this first one does not work in Python 3
print >> sys.stderr, "spam"
sys.stderr.write("spam\n")
os.write(2, b"spam\n")
from __future__ import print_function
print("spam", file=sys.stderr)
To wydaje się być sprzeczne z zen z Pythona nr 13 † , więc jaka jest tutaj różnica i czy są jakieś zalety lub wady w ten czy inny sposób? Który sposób należy zastosować?
† Powinien istnieć jeden - a najlepiej tylko jeden - oczywisty sposób na zrobienie tego.
Odpowiedzi:
Odkryłem, że jest to jedyny krótki + elastyczny + przenośny + czytelny:
Z funkcji
eprint
można korzystać tak samo, jak w przypadkuprint
funkcji standardowej :źródło
print
w całym programie. Tylko w module zawierającym definicjęeprint()
. Umieść go sam w małym pliku, zaimportujeprint
z niego do innych plików, a będziesz mógł używać instrukcjiprint
tak długo, jak chcesz.To mój wybór, tylko bardziej czytelny i mówiący dokładnie, co zamierzasz robić, i przenośny w różnych wersjach.
Edycja: bycie „pytonicznym” to dla mnie trzecia myśl na temat czytelności i wydajności ... mając na uwadze te dwie rzeczy, z pythonem 80% twojego kodu będzie pytoniczne. rozumienie listy jest „wielką rzeczą”, która nie jest używana tak często (czytelność).
źródło
print
instrukcji jest łatwe drukowanie wartości nieciągłych, bez konieczności ich wcześniejszej konwersji. Jeśli potrzebujesz instrukcji print,sys.stderr.write()
jest niczymprint
. Nie dodaje nowej linii.os.linesep
. Wstderr
końcu o tym mówimy. Nie chcę, aby konsola zepsuła się z niewłaściwym nowym wierszem.print >> sys.stderr
zniknął w Python3. http://docs.python.org/3.0/whatsnew/3.0.html mówi:Dla wielu z nas przeniesienie miejsca docelowego na koniec polecenia wydaje się nieco nienaturalne. Alternatywa
wygląda bardziej obiektowo i elegancko przechodzi od ogólnej do szczegółowej. Pamiętaj jednak, że
write
nie jest to zamiennik 1: 1 dlaprint
.źródło
print('spam', file=sys.stderr)
. Jeśli robisz to w kółko, możesz zakodować funkcję „eprint” jak w najpopularniejszej odpowiedzi, ale w takim przypadku zapytałbym, co jest nie tak z logowaniem? stackoverflow.com/a/41304513/1450294with sys.stderr as dest:
przed wciętym wezwaniem doprint("ERROR", file=dest)
Nikt
logging
jeszcze nie wspomniano , ale rejestrowanie zostało utworzone specjalnie w celu przekazywania komunikatów o błędach. Podstawowa konfiguracja skonfiguruje obsługę strumienia zapisującą do stderr.Ten skrypt:
ma następujący wynik po uruchomieniu w wierszu poleceń:
i bar.txt będzie zawierać „hello world” wydrukowany na standardowym wyjściu.
źródło
W przypadku Pythona 2 mój wybór to:
print >> sys.stderr, 'spam'
Ponieważ możesz po prostu wydrukować listy / dykty itp. Bez konwersji na ciąg znaków.print >> sys.stderr, {'spam': 'spam'}
zamiast:sys.stderr.write(str({'spam': 'spam'}))
źródło
"{0}".format({'spam': 'spam'})
, prawda? Powiedziałbym, że powinieneś unikać jawnej konwersji na ciąg. Edycja: I przypadkowo gramatykaZrobiłem następujące przy użyciu Python 3:
Teraz mogę dodać na przykład argumenty słów kluczowych, aby uniknąć powrotu karetki:
źródło
Powiedziałbym, że twoje pierwsze podejście:
to „Jeden ... oczywisty sposób na to” Inni nie spełniają zasady nr 1 („Piękne jest lepsze niż brzydkie”)
źródło
>>
oznacza składniowo? Rozumiem, że jest to próba skopiowania basha>
, więc czy jest to jakaś składnia typu boothorned?std::cout << "spam";
To naśladuje standardową funkcję drukowania, ale wyświetla na stderr
źródło
print
nie obejmuje koloru.W Pythonie 3 można po prostu użyć print ():
prawie po wyjęciu z pudełka:
lub:
Jest to proste i nie musi zawierać niczego poza
sys.stderr
.źródło
EDYCJA Z perspektywy czasu myślę, że potencjalne zamieszanie związane ze zmianą sys.stderr i brakiem aktualizacji zachowania powoduje, że ta odpowiedź nie jest tak dobra, jak zwykła funkcja, jak zauważyli inni.
Użycie tylko częściowego oszczędza 1 linię kodu. Potencjalne zamieszanie nie jest warte zapisania 1 linii kodu.
oryginalny
Aby było to jeszcze łatwiejsze, oto wersja, która używa „częściowego”, co stanowi dużą pomoc w zawijaniu funkcji.
Następnie używasz go w ten sposób
Możesz sprawdzić, czy drukuje na stderr, a nie na stdout, wykonując następujące czynności (nadrzędny kod z http://coreygoldberg.blogspot.com.au/2009/05/python-redirect-or-turn-off-stdout-and .html ):
Minusem tego jest częściowe przypisanie wartości sys.stderr do zawiniętej funkcji w momencie tworzenia. Co oznacza, że jeśli przekierujesz stderr później, nie wpłynie to na tę funkcję. Jeśli planujesz przekierować stderr, użyj ** metody kwargs wspomnianej przez aaguirre na tej stronie.
źródło
To samo dotyczy standardowego wyjścia:
Jak stwierdzono w innych odpowiedziach, print oferuje ładny interfejs, który jest często wygodniejszy (np. Do drukowania informacji debugowania), podczas gdy zapis jest szybszy i może być również wygodniejszy, gdy trzeba sformatować dane wyjściowe dokładnie w określony sposób. Rozważałbym również łatwość konserwacji:
Możesz później zdecydować się na przełączenie między stdout / stderr a zwykłym plikiem.
Składnia print () zmieniła się w Pythonie 3, więc jeśli potrzebujesz obsługiwać obie wersje, write () może być lepszy.
źródło
from __future__ import print_function
jest lepszym sposobem na obsługę zarówno Python 2.6+, jak i Python 3.Pracuję w Pythonie 3.4.3. Wycinam trochę pisania, które pokazuje, jak się tu dostałem:
Zadziałało? Spróbuj przekierować stderr do pliku i zobacz, co się stanie:
Cóż, poza tym, że małe wprowadzenie, które daje ci Python, zostało zawieszone w stderr (gdzie indziej by poszło?), Działa.
źródło
Jeśli wykonasz prosty test:
Przekonasz się, że sys.stderr.write () jest konsekwentnie 1,81 razy szybszy!
źródło
Jeśli chcesz wyjść z programu z powodu błędu krytycznego, użyj:
i
import sys
w nagłówku.źródło
Różnica między funkcją drukowania a funkcją zapisu stderr : stderr : stderr (błąd standardowy) jest potokiem wbudowanym w każdy system UNIX / Linux, gdy twój program ulega awarii i drukuje informacje debugowania (jak traceback w Pythonie), przechodzi do stderr rura.
print : print to opakowanie, które formatuje dane wejściowe (dane wejściowe to spacja między argumentem a znakiem nowej linii na końcu), a następnie wywołuje funkcję zapisu danego obiektu, domyślnie dany obiekt to sys.stdout, ale możemy przekazać plik, tzn. możemy również wydrukować dane wejściowe w pliku.
Python2: Jeśli więc używamy Python2
http://python3porting.com/noconv.html
https://docs.python.org/2/library/logging.html#logger-objects
źródło