Zanurkuj w Pythonie/Pakiety: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
zamiana {{Nawigacja|Python|->{{Nawigacja|Zanurkuj w Pythonie| [[Python/->[[../
Piotr (dyskusja | edycje)
poprawki
Linia 1:
{{Podświetl|py}}
== Pakiety ==
 
W rzeczywistości przetwarzanie dokumentu XML jest bardzo proste, wystarczy jedna linia kodu. Jednakże, zanim dojdziemy do tej linii kodu, będziemy musieli krótko omówić, czym są pakiety.
 
'''{{Python/Przykład
|9.5. |Ładowanie dokumentu XML'''
|tekst=
 
>>> from xml.dom import minidom #(1)
>>> xmldoc = minidom.parse('~/diveintopython/common/py/kgp/binary.xml')
 
# Tej składni jeszcze nie widziałeświdzieliśmy. Wygląda to niemal, jak <ttcode>from module import</ttcode>, który znamy i kochamy, ale z "." wygląda na coś wyższego i innego niż proste <ttcode>import</ttcode>. Tak na prawdę <ttcode>xml</ttcode> jest czymś, co jest znane pod nazwą ''pakiet'' (ang. ''package''), <ttcode>dom</ttcode> jest zagnieżdżonym pakietem wewnątrz <ttcode>xml</ttcode>-a, a <ttcode>minidom</ttcode> jest modułem znajdującym się wewnątrz <ttcode>xml.dom</ttcode>.
}}
 
Brzmi to skomplikowanie, ale tak naprawdę nie jest. Jeśli spojrzymy na konkretną implementację, może nam to pomóc. Pakiet to niewiele więcej niż katalog z modułami, a zagnieżdżone pakiety są podkatalogami. Moduły wewnątrz pakietu (lub zagnieżdżonego pakietu) są nadal zwykłymi plikami <tt>.py</tt> z wyjątkiem tego, że są w podkatalogu, zamiast w głównym katalogu <tt>lib/</tt> Twojej instalacji Pythona.
 
Brzmi to skomplikowanie, ale tak naprawdę nie jest. Jeśli spojrzymy na konkretną implementację, może nam to pomóc. Pakiet to niewiele więcej niż katalog z modułami, a zagnieżdżone pakiety są podkatalogami. Moduły wewnątrz pakietu (lub zagnieżdżonego pakietu) są nadal zwykłymi plikami <tt>.py</tt> z wyjątkiem tego, że są w podkatalogu, zamiast w głównym katalogu <tt>lib/</tt> Twojej instalacji Pythona.
'''Przykład 9.6. Plikowa struktura pakietu'''
 
{{Python/Przykład
'''Przykład |9.6. |Plikowa struktura pakietu'''
|tekst=
<span>Python21/ katalog główny instalacji Pythona (katalog domowy plików wykonywalnych)
|
Linia 27 ⟶ 29:
+−−parsers/ pakiet xml.parsers (używany wewnętrznie)</span>
 
Dlatego kiedy powiesz <ttcode>from xml.dom import minidom</ttcode>, Python zrozumie to jako "znajdź w katalogu <tt>xml</tt> katalog <tt>dom</tt>, a następnie szukaj tutaj modułu <ttcode>minidom</ttcode> i zaimportuj go jako <ttcode>minidom</ttcode>". Lecz Python jest nawet mądrzejszy; nie tylko możeszmożemy zaimportować cały moduł zawarty wewnątrz pakietu, ale także możeszmożemy wybiórczo zaimportować wybrane klasy czy funkcje z modułu znajdującego się wewnątrz pakietu. MożeszMożemy także zaimportować sam pakiet jako moduł. Składnia będzie taka sama; Python wywnioskuje, co masz na myśli na podstawie struktury plików pakietu i automatycznie wykona poprawną czynność.
 
'''Przykład 9.7. Pakiety także są modułami'''
 
{{Python/Przykład
'''Przykład |9.7. |Pakiety także są modułami'''
|tekst=
>>> from xml.dom import minidom #(1)
>>> minidom
{{samp|<module 'xml.dom.minidom' from 'C:\Python21\lib\xml\dom\minidom.pyc'>}}
>>> minidom.Element
{{samp|<class xml.dom.minidom.Element at 01095744>}}
>>> from xml.dom.minidom import Element #(2)
>>> Element
{{samp|<class xml.dom.minidom.Element at 01095744>}}
>>> minidom.Element
{{samp|<class xml.dom.minidom.Element at 01095744>}}
>>> from xml import dom #(3)
>>> dom
{{samp|<module 'xml.dom' from 'C:\Python21\lib\xml\dom\__init__.pyc'>}}
>>> import xml #(4)
>>> xml
{{samp|<module 'xml' from 'C:\Python21\lib\xml\__init__.pyc'>}}
 
# W tym miejscu importujemy moduł (<ttcode>minidom</ttcode>) z zagnieżdżonego pakietu (<ttcode>xml.dom</ttcode>). W wyniku tego <ttcode>minidom</ttcode> został zaimportowany do Twojejnaszej przestrzeni nazw. Aby się odwołać do klasy wewnątrz tego modułu (np. <ttcode>Element</ttcode>), będzieszbędziemy musiałmusieli nazwę klasy poprzedzić nazwą modułu.
# Tutaj importujeszimportujemy klasę (<ttcode>Element</ttcode>) z modułu (<ttcode>minidom</ttcode>), a ten moduł z zagnieżdżonego pakietu (<ttcode>xml.dom</ttcode>). W wyniku tego <ttcode>Element</ttcode> został zaimportowany bezpośrednio do Twojejnaszje przestrzeni nazw. Dodajmy, że nie koliduje to z poprzednim importem; teraz do klasy <ttcode>Element</ttcode> możemy się odwoływać na dwa sposoby (lecz nadal jest to ta sama klasa).
# W tym miejscu importujemy pakiet <ttcode>dom</ttcode> (zagnieżdżony pakiet <ttcode>xml</ttcode>-a) jako sam w sobie moduł. Dowolny poziom pakietu może być traktowany jako moduł, co zresztą zobaczymy za moment. Może nawet mieć swoje własne atrybuty i metody, tak jak moduły, które widzieliśmy wcześniej.
# Tutaj importujemy jako moduł główny poziom pakietu <ttcode>xml</ttcode>.
}}
 
Więc jak może pakiet (który na dysku jest katalogiem) zostać zaimportowany i traktowany jako moduł (który jest zawsze plikiem na dysku)? Odpowiedzią jest magiczny plik <tt>__init__.py</tt>. WidzimyWiemy, że pakiety nie są po prostu katalogami., ale są one katalogami ze specyficznym plikiem wewnątrz, <tt>__init__.py</tt>. Plik ten definiuje atrybuty i metody tego pakietu. Na przykład, <ttcode>xml.dom</ttcode> posiada klasę <ttcode>Node</ttcode>, która jest zdefiowanazdefiniowana w <tt>xml/dom/__init__.py</tt>. Kiedy importujeszimportujemy pakiet jako moduł (np. <ttcode>dom</ttcode> z <ttcode>xml</ttcode>-a), to tak naprawdę importujeszimportujemy jego plik <tt>__init__.py</tt>.
 
{{Infobox|
Linia 59 ⟶ 63:
}}
 
Więc dlaczego męczyć się z pakietami? Umożliwiają one logiczne pogrupowanie powiązanych ze sobą modułów. Zamiast stworzenia pakietu <ttcode>xml</ttcode> z wewnętrznymi pakietami <ttcode>sax</ttcode> i <ttcode>dom</ttcode>, autorzy mogliby umieścić całą funkcjonalność <ttcode>sax</ttcode> w <tt>xmlsax.py</tt>, a całą funkcjonalność <ttcode>dom</ttcode> w <tt>xmldom.py</tt>, czy też nawet zamieścić wszystko w pojedyńczympojedynczym module. Jednak byłoby to niewygodne (podczas pisania tego podręcznika pakiet <ttcode>XMLxml</ttcode> posiadał prawie 6000 linii kodu) i trudne w zarządzaniu
(dzięki oddzielnym plikom źródłowym, wiele osób może równocześnie pracować nad różnymi częściami).
 
Jeśli kiedykolwiek będzieszbędziemy planowałplanowali napisać wielki podsystem w Pythonie (lub co bardziej prawdopodobne, kiedy zauważyszzauważymy, że twójnasz mały podsystem rozrósł się do dużego), zainwestujzainwestujmy trochę czasu w zaprojektowanie dobrej architektury systemu pakietów. Jest to jedna z wielu rzeczy w Pythonie, w których jest dobry, więc skorzystajmy z tej zalety.
 
<noinclude>
{{Nawigacja|Zanurkuj w Pythonie|
[[../Przetwarzanie XML-a|Nurkujemy]]|
[[../Parsowanie XML-a|Parsowanie XML-a/]]|
}}
{{Podświetl|py}}
</noinclude>