Zanurkuj w Pythonie/Standardowy strumień wejścia, wyjścia i błędów: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Piotr (dyskusja | edycje)
koniec
orty i styl
Linia 2:
== Standardowy strumień wejścia, wyjścia i błędów==
 
Użytkownicy Uniksa są już prawdopodobnie prawdopodobnie zapoznani z koncepcją standardowego wejścia, standardowego wyjścia i standardowego strumienia błędów. PodrozdziałTen tenpodrozdział jest dla pozostałych osób.
 
Standardowe wyjście i strumień błędów (powszechnie używana skrócona forma to ''stdout'' i ''stderr'') są strumieniami danych wbudowanymi do każdego systemu Unix. Kiedy coś wypisujesz, idzie to do strumienia ''stdout''; kiedy wystąpi błąd w twoim programie, a program wypisze informacje pomocne przy debugowaniu (jak traceback w Pythonie), to wszystko pójdzie do strumienia <tt>stderr</tt>. Te dwa strumienie są zwykle połączone z oknem terminala, na któryktórym pracujesz, więc jeśli cośjeżeli program coś wypisuje, zobaczysz to na wyjściu, a kiedy program sięspowoduje rozwalibłąd, zobaczymy informacje debugujące. (Jeśli pracujesz naw systemie z okienkowym IDE Pythona, ''stdout'' i ''stderr'' domyślnie będą połączone z twoim „interaktywnym oknem”.)
 
'''Przykład 10.8. Wprowadzenie do ''stdout'' i ''stderr'''''
Linia 49:
fsock.close() #(7)
 
# To zostanie wypisane w interaktywnym oknie IDE (lub w terminalu, jeśli skrypt został uruchomiony wz linii poleceń).
# Zawsze, zanim przekierujemy standardowe wyjście, przypisujemy gdzieś <tt>stdout</tt>, dzięki temu, będziemy potem mogli do niego normalnie wrócić.
# Otwieramy plik do zapisu. Jeśli plik nie istnieje, zostanie utworzoneutworzony. Jeśli istnieje, zostanie nadpisany.
# Całe późniejsze wyjście zostanie przekierowane do pliku, który właśnie otworzyliśmy.
# Zostanie to wypisane tylko do pliku <tt>out.log</tt>; nie będzie widoczne w oknie IDE lub w terminalu.
# Przywracamy <tt>stdout</tt> do początkowej postaci, zanimoryginalnej zaczęliśmy się w nim babraćpostaci.
# Zamykamy plik <tt>out.log</tt>.
 
Linia 78:
 
# Otwieramy plik <tt>error.log</tt>, gdzie chcemy przechowywać informacje debugujące.
# Przekierowujemy standardowy strumień błędów, dzięki przypisaniu obiektu pliku nowo otwartego pliku do <tt>sys.stderr</tt>.
# Rzucamy wyjątek. Zauważmy, że na ekranie wyjściowym nic nie zostanie wypisane. Wszystkie informacje ''traceback'' zostały zapisane w <tt>error.log</tt>.
# Zauważmy także, że nie zamkneliśmyzamknęliśmy wyraźniejawnie pliku error.log, a nawet nie przypisaliśmy do <tt>sys.stderr</tt> jestjego pierwotnej wartości. To jest wspaniałe, że kiedy program się rozwali (z powodu wyjątku), Python wyczyści i zamknie wszystkie pliki za nas. Nie ma żadnej różnicy, czy <tt>stderr</tt> zostanie przywrócony, czy też nie, ponieważ program się rozwala, a Python kończy działanie. Przywrócenie wartości do orginalnejoryginalnej, jest bardziej ważne dla <tt>stdout</tt>, jeśli zamierzasz później wykonywać jakieś inne operacje w tym samym skrypcie.
 
Ponieważ powszechnie wypisuje się informacje o błędach na standardowy strumień błędów, Python posiada skrótową składnie, która można wykorzystać do bezpośredniego przekierowywania wyjścia.
Linia 120:
# Dzięki temu po prostu wypiszemy całą zawartość pliku <tt>binary.xml</tt>. (Użytkownicy Windowsa powinni wykorzystać polecenie <tt>type</tt> zamiast <tt>cat</tt>.)
# Polecenie to wypisuje zawartość pliku <tt>binary.xml</tt>, ale znak "|" (ang. ''pipe''), oznacza, że standardowe wyjście nie zostanie wypisana na ekran. Zamiast tego, zawartość standardowego wyjścia zostanie wykorzystane jako standardowe wejście następnego programu, który w tym przypadku jest skryptem Pythona.
# Zamiast określać modułu (np. <tt>binary.xml</tt>), dajemy "-", który każe naszemynaszemu skryptowi wczytać gramatykę ze standardowego wejścia, zamiast z określonego pliku na dysku. (Więcej o tym, w jaki sposób to się dzieje w następnym przykładzie.) Zatem efekt będzie taki sam, jak w pierwszym poleceniu, gdzie bezpośrednio określamy plik gramatyki, ale tutaj zwróćmy uwagę na rozszerzone możliwości. Zamiast wywoływać <tt>cat binary.xml</tt>, moglibyśmy uruchomić skrypt, który by dynamicznie generował gramatykę, a następnie mógłby ją doprowadzić do naszego skryptu. Dane mogłyby przyjść skądkolwiek: z bazy danych, innego skryptu generującego gramatykę lub jeszcze inaczej. Zaletą tego jest to, że nie musimy zmieniać w żaden sposób <tt>kgp.py</tt>, aby dołączyć jakąś funkcjonalność. Jedynie, co potrzebujemy, to możliwość wczytania gramatyki ze standardowego wejścia, a całą logikę dodatkowej funkcjonalności możemy rozdzielić wewnątrz innego programu.
 
Więc w jaki sposób skrypt "wie", żeby czytać ze standardowego wejścia, gdy plik gramatyki to "-"? To nie jest żadna magia; to tylko właśnie prosty kod.