Zanurkuj w Pythonie/Abstrakcyjne źródła wejścia: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
ok, przetłumaczone |
Nie podano opisu zmian |
||
Linia 2:
== Abstrakcyjne źródła wejścia ==
Jedną z najważniejszych możliwości Pythona jest jego dynamiczne
Wiele funkcji, które wymagają jakiegoś źródła wejścia, mogłyby po prostu przyjmować jako argument nazwę pliku, następnie go otwierać, czytać, a na końcu go zamykać. Jednak tego nie robią. Zamiast działać w ten sposób, jako argument przyjmują obiekt pliku lub ''obiekt pliko-podobny''.
W najprostszym przypadku ''obiekt pliko-podobny'' jest dowolnym obiektem z metodą <tt>read</tt>, która przyjmuje opcjonalny parametr wielkości <tt>size</tt>, a następnie zwraca łańcuch znaków. Kiedy wywołujemy go bez parametru <tt>size</tt>, odczytuje
Powyżej opisaliśmy, w jaki sposób działają prawdziwe pliki. Jednak nie musimy się ograniczać do prawdziwych plików. Źródłem wejścia może być wszystko: plik na dysku, strona internetowa, czy nawet jakiś łańcuch znaków. Dopóki przekazujesz do funkcji ''obiekt pliko-podobny'', a funkcja ta po prostu wywołuje metodę <tt>read</tt>, to funkcja może obsłużyć dowolny rodzaj wejścia, bez posiadania jakiegoś specjalnego kodu dla każdego rodzaju wejścia.
Może się zastanawiasz, co ma to wspólnego z przetwarzaniem XML-a? Otóż <tt>minidom.parse</tt> jest taką
'''Przykład 10.1. Parsowanie XML-u z pliku'''
Linia 34:
# Najpierw otwieramy plik z dysku. Otrzymujemy przez to obiekt pliku.
# Przekazujemy obiekt pliku do funkcji <tt>minidom.parse</tt>,
# Koniecznie wywołujemy metodę <tt>close</tt>
# Wywołując
Dobrze, to wszystko wygląda jak kolosalne marnotrawstwo czasu.
'''Przykład 10.2. Parsowanie XML-a z URL-a '''
Linia 73:
# Jak już zaobserwowaliśmy w poprzednim rozdziale, <tt>urlopen</tt> przyjmuje adres URL strony internetowej i zwraca ''obiekt pliko-podobny''. Ponadto, co jest bardzo ważne, obiekt ten posiada metodę <tt>read</tt>, która zwraca źródło danej strony internetowej.
# Teraz przekazujemy ten ''obiekt pliko-podobny'' do <tt>minidom.parse</tt>,
# Jak tylko ''obiekt pliko-podobny'', który podarował nam <tt>urlopen</tt>, nie będzie potrzebny, koniecznie zamykamy go.
# Przy okazji, ten URL jest prawdziwy i on naprawdę jest dokumentem XML. Reprezentuje on aktualne nagłówki, techniczne newsy i plotki w [http://slashdot.org/ Slashdot].
'''Przykład 10.3.
<nowiki>
Linia 91:
OK, to możemy korzystać z funkcji <tt>minidom.parse</tt> zarówno do parsowania lokalnych plików jak i odległych URL-ów, ale do parsowania łańcuchów znaków wykorzystujemy... inną funkcję. Oznacza to, że jeśli chciałbyś móc dać wyjście z pliku, adresu URL lub łańcucha znaków, potrzebujesz specjalnej logiki, aby sprawdzić czy mamy do czynienia z łańcuchem znaków, a jeśli tak, to wywołać funkcję <tt>parseString</tt> zamiast <tt>parse</tt>. Jakie to niesatysfakcjonujące.
'''Przykład 10.4. Wprowadzenie do StringIO'''
Linia 113:
# Moduł <tt>StringIO</tt> zawiera tylko jedną klasę, także nazwaną <tt>StringIO</tt>, która pozwala zamienić napis w ''obiekt pliko-podobny''. Klasa <tt>StringIO</tt>, podczas tworzenia instancji, przyjmuje jako parametr łańcuch znaków.
# Teraz już mamy ''obiekt pliko-podobny'' i możemy robić wszystkie możliwe ''pliko-podobne'' operacje. Na przykład <tt>read</tt>,
# Wywołując ponownie <tt>read</tt> otrzymamy pusty napis. W ten sposób działa prawdziwy obiekt pliku; kiedy już zostanie przeczytany cały plik, nie można czytać więcej bez wyraźnego przesunięcia do początku pliku. Obiekt <tt>StringIO</tt> pracuje w ten sam sposób.
# Możemy
# Możemy także czytać fragmentami łańcuch znaków, przekazując parametr wielkości <tt>size</tt> do metody <tt>read</tt>.
# Za każdym razem, kiedy wywołamy <tt>read</tt>, zostanie nam zwrócona pozostała część napisu, która nie została jeszcze przeczytana. W dokładnie ten sam sposób działa obiekt pliku.
Linia 132:
# Teraz możemy przekazać obiekt pliko-podobny (w rzeczywistości <tt>StringIO</tt>) do <tt>minidom.parse</tt>, który wywoła metodę <tt>read</tt> z tego obiektu i szczęśliwie wszystko przeparsuje, nie zdając sobie nawet sprawy, że wejście to pochodzi z łańcucha znaków.
To już wiemy, jak za pomocą
'''Przykład 10.6. <tt>openAnything</tt>'''
Linia 159:
# Najpierw sprawdzamy, czy <tt>source</tt> jest URL-em. Robimy to brutalnie: próbujemy otworzyć to jako URL i cicho pomijamy błędy spowodowane próbą otworzenia czegoś, co nie jest URL-em. Jest to właściwie eleganckie w tym sensie, że jeśli <tt>urllib</tt> będzie kiedyś obsługiwał nowe typy URL-i, nasz program także je obsłuży i to bez konieczności zmiany kodu. Jeśli <tt>urllib</tt> jest w stanie otworzyć <tt>source</tt>, to <tt>return</tt> wykopie nas bezpośrednio z funkcji i poniższe instrukcje <tt>try</tt> nie będą nigdy wykonywane.
# W innym przypadku, gdy <tt>urllib</tt> wrzasnął na nas i powiedział, że <tt>source</tt> nie jest poprawnym URL-em, zakładamy, że jest to ścieżka do pliku znajdującym się na dysku i próbujemy go otworzyć. Ponownie, nic nie robimy, by sprawdzić, czy <tt>source</tt> jest poprawną nazwą pliku (zasady określające poprawność nazwy pliku są szalenie różne na różnych platformach, dlatego prawdopodobnie i tak byśmy to źle zrobili). Zamiast tego, na ślepo otwieramy plik i cicho pomijamy wszystkie błędy.
# W tym miejscu zakładamy, że <tt>source</tt> jest łańcuchem znaków, który przechowuje dokument XML (ponieważ nic innego nie zadziałało), dlatego wykorzystujemy <tt>StringIO</tt>, aby utworzyć ''obiekt pliko-podobny'' i zwracamy go. (Tak naprawdę, ponieważ wykorzystujemy
Teraz możemy wykorzystać
'''Przykład 10.7. Wykorzystanie <tt>openAnything</tt> w kgp.py'''
|