W chwili gdy zakończy się pracę w interpreterze Pythona i ponownie rozpocznie, wszystkie definicje, które wprowadzono (funkcje i zmienne) zostają stracone. Dlatego też, jeśli chce się napisać ździebko dłuższy program, lepiej będzie gdy użyje się edytora tekstów do przygotowania poleceń dla interpretera i uruchomi go z przygotowanym plikiem na wejściu. Nazywa się to tworzeniem skryptu6.1W miarę,, jak twój program staje się dłuższy, zajdzie konieczność podzielenia go na kilka plików w celu łatwiejszej pielęgnacji 6.2 całości. Będziesz chciał również użyć funkcji, które właśnie napisałeś w paru innych programach bez potrzeby wklejania ich w każdy program z osobna.
Python wspomoże te działania poprzez pewien sprytny mechanizm umieszczania definicji w pliku i używania ich w skrypcie lub w interaktywnej postaci interpretera. Taki plik nazywany jest modułem: definicje z modułu mogą być importowane do innych modułów lub do głównego modułu (zestaw zmiennych, których używałeś w skrypcie wykonywanym na najwyższym poziomie i w trybie kalkulatora).
Moduł jest plikiem zawierającym definicje Pythona i jego instrukcje. Nazwa
pliku jest nazwą modułu pozbawionego rozszerzenia .py. W module, nazwa
modułu dostępna jest jako wartość zmiennej globalnej __name__. Na
przykład, użyj swojego ulubionego edytora tekstów6.3 i stwórz plik o nazwie
fibo.py. Umieść go w bieżącym katalogu z następującą zawartością:
# Moduł liczb Fibonacciego
def fib(n): # wypisz ciąg Fibonacciego aż do n
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
def fib2(n): # zwróć ciąg Fibonacciego aż do n
wybik = []
a, b = 0, 1
while b < n:
wynik.append(b)
a, b = b, a+b
return wynik
Teraz, po uruchomieniu interpretera Pythona można zaimportować ten moduł za pomocą następującego polecenia:
>>> import fibo
W ten sposób nie zaimportuje się nazw funkcji zdefiniowanych w module
fibo wprost do bieżącej tablicy symboli: to polecenie wprowadza tylko
nazwę fibo do tej tablicy. Aby dostać się do owych
funkcji, trzeba użyć nazwy modułu:
>>> fibo.fib(1000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>> fibo.fib2(100) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] >>> fibo.__name__ 'fibo'
>>> fib = fibo.fib >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Moduł może zawierać instrukcje wykonywalne obok definicji funkcji. Instrukcje te mają na celu inicjalizację modułu. Wykonywane są tylko w chwili importowania modułu po raz pierwszy, gdzieś w programie.6.4
Każdy z modułów posiada swoją prywatną tablicę symboli, która używana jest
przez wszystkie funkcje zdefiniowane w module jako globalna tablica
symboli. W ten sposób, autor modułu może używać w nim zmiennych globalnych
bez konieczności martwienia się o przypadkowy konflikt nazwy występującej w
module z nazwą globalną zdefiniowaną w programie użytkownika.
Z drugiej jednak strony, jeżeli wiesz co robisz, można wpłynąć na globalną
zmienną modułu za pomocą takiej samej notacji, jakiej użyliśmy poprzednio, aby
użyć wprost nazwy funkcji z modułu: nazwa_modulu.nazwa_elementu.
Moduły mogą importować inne moduły. Zazwyczaj, acz nie jest to wymagane, wszystkie instrukcje import umieszczane są na początku modułu (lub skryptu). Nazwy zaimportowanych modułów umieszczane są w globalnej tablicy symboli importujących modułów.
Istnieje wariant instrukcji import, która importuje nazwy z modułu wprost do tablicy symboli modułów importujących. Na przykład:
>>> from fibo import fib, fib2 >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Ta konstrukcja nie wprowadza nazwy modułu, z którego importujemy, do
lokalnej tablicy symboli (tak więc, w tym przykładzie fibo nie jest
zdefiniowane).
Jest też pewien wariant, który importuje wszystkie nazwy z modułu:
>>> from fibo import * >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Ten mechanizm pozwala zaimportować wszystkie nazwy z wyjątkiem tych, które
zaczynają się od znaku podkreślenia (_).
Gdy moduł o nazwie pomyje jest importowany, interpreter poszukuje pliku o nazwie pomyje.py w bieżącym katalogu, następnie w katalogach określonych przez zmienną systemową PYTHONPATH. Zmienna ta ma taką samą składnię co zmienna PATH, tzn. jest listą katalogów. W przypadku, gdy PYTHONPATH nie jest określona, lub gdy plik nie jest znaleziony w katalogach tam wymienionych, poszukiwanie kontynuowane jest na ścieżkach ustawionych w momencie instalacji: na jest to zazwyczaj .:/usr/local/lib/python.
Na samym końcu, moduły poszukiwane są na liście katalogów umieszczonych w
zmiennej pythonowej sys.path, która inicjalizowana jest nazwami
katalogu zawierającego skrypt wejściowy (lub z bieżącego katalogu), zawartością
zmiennej PYTHONPATH i domyślnymi katalogami instalacyjnymi.
W ten sposób zmyślne programy w Pythonie mogą modyfikować a nawet zastępować
ścieżkę poszukiwań modułów. Zobacz później podrozdział na temat standardowych
modułów.
Ważnym czynnikiem przyspieszenia rozruchu dla małych programów, które używają mnóstwo standardowych modułów jest obecność pliku pomyje.pyc. W pliku tym zawarta jest skompilowana już ,,bajt-kodowa''6.5wersja modułu spam. Czas modyfikacji wersji pliku pomyje.py, z którego powstał pomyje.pyc, jest zarejestrowany w tymże ostatnim. Plik .pyc jest ignorowany, jeżeli oba te czasy nie pasują do siebie6.6
W normalnych warunkach, nie trzeba zrobić nic szczególnego, aby utworzyć plik pomyje.pyc. Kiedykolwiek pomyje.py zostało pomyślnie skompilowane, interpreter usiłuje zapisać skompilowana wersję do pomyje.pyc. Nie ma błędu, jeśli zapis się nie powiedzie. Jeżeli z jakiegokolwiek powodu plik ten nie został zapisany, to pomyje.pyc zostanie rozpoznane jako niepoprawny i zignorowany. Zawartość pomyje.pyc jest niezależna od platformy, tak więc katalog modułów może być dzielony pomiędzy maszynami o różnej architekturze.6.7
Parę wskazówek dla ekspertów:
SET_LINENO. Gdy używasz
-O, cały kod pośredni jest optymalizowany, pliki
.pyc są ignorowane, a pliki .py kompilowane do zoptymalizowanego
kodu pośredniego.
__doc__ usuwane są z kodu
pośredniego, co objawia się mniejszymi plikami .pyo. Ponieważ
działanie niektórych programów może zależeć od obecności tych zmiennych,
powinno się używać tej opcji tylko wtedy gdy jest się pewnym, co się robi.
Python dostarczany jest z biblioteką standardowych modułów, które opisane są w
osobnym dokumencie: Opis biblioteki Pythona
(inaczej «Opis biblioteki»). Niektóre moduły wbudowane są w interpreter: są
one źródłem tych operacji, które nie są częścią jądra6.8 języka, lecz pomimo tego zostały wbudowane albo z powodu
wydajności, lub aby wprowadzić dostęp do podstawowych operacji systemu
operacyjnego, np. funkcje systemowe. To co zostało wbudowane w interpreter,
jest kwestią opcji instalacji, tzn. moduł ameba dostarczany jest tylko
na te systemy, które w pewien sposób wspomagają podstawowe operacje Ameby.
Jeden z modułów wbudowanych zasługuje na szczególną uwagę:
sys , który jest wbudowany w niemal każdy
interpreter Pythona. Zmienne sys.ps1 i sys.ps2 definiują napisy
używane jako pierwszy i drugi znak zachęty:
>>> import sys >>> sys.ps1 '>>> ' >>> sys.ps2 '... ' >>> sys.ps1 = 'C> ' C> print 'Yuck!' Yuck! C>
Zmienne te dostępne są tylko w trybie interakcyjnym interpretera.
Zmienna sys.path jest listą napisów, które decydują o ścieżce poszukiwań
modułów przez interpreter. Domyślnie inicjowane są zawartością zmiennej
systemowej PYTHONPATH lub wbudowanymi domyślnymi katalogami
poszukiwań, jeśli PYTHONPATH nie istnieje. Można modyfikować
sys.path poprzez standardowe operacje na listach:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
Funkcja wbudowana dir() służy do znajdywania wszystkich nazw, które są zdefiniowane w module. Zwraca ona posortowaną listę napisów:
>>> import fibo, sys >>> dir(fibo) ['__name__', 'fib', 'fib2'] >>> dir(sys) ['__name__', 'argv', 'builtin_module_names', 'copyright', 'exit', 'maxint', 'modules', 'path', 'ps1', 'ps2', 'setprofile', 'settrace', 'stderr', 'stdin', 'stdout', 'version']
Wywołana bez argumentów dir() zwróci listę nazw, które właśnie zdefiniowałeś:
>>> a = [1, 2, 3, 4, 5] >>> import fibo, sys >>> fib = fibo.fib >>> dir() ['__name__', 'a', 'fib', 'fibo', 'sys']
Zauważ, że zwrócona została lista wszystkich typów nazw: zmiennych, modułów, funkcji, itd.
dir() nie poda listy nazw funkcji i zmiennych wbudowanych. Jeśli chce się uzyskać taką listę, to posłuż się standardowym modułem __builtin__ :
>>> import __builtin__ >>> dir(__builtin__) ['AccessError', 'AttributeError', 'ConflictError', 'EOFError', 'IOError', 'ImportError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'MemoryError', 'NameError', 'None', 'OverflowError', 'RuntimeError', 'SyntaxError', 'SystemError', 'SystemExit', 'TypeError', 'ValueError', 'ZeroDivisionError', '__name__', 'abs', 'apply', 'chr', 'cmp', 'coerce', 'compile', 'dir', 'divmod', 'eval', 'execfile', 'filter', 'float', 'getattr', 'hasattr', 'hash', 'hex', 'id', 'input', 'int', 'len', 'long', 'map', 'max', 'min', 'oct', 'open', 'ord', 'pow', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'round', 'setattr', 'str', 'type', 'xrange']
Pakiety są sposobem na ,,ustrukturalnienie'' przestrzeni nazw modułów Pythona poprzez używanie ,,kropkowanych nazw modułów''. Na przykład, nazwa modułu A.B oznacza moduł składowy "B" pakietu "A". Tak samo jak używanie modułów zaoszczędza autorom różnych modułów martwienia się o konflikt nazw globalnych, tak samo używanie kropkowanych nazw modułów zaoszczędza autorom wielomodułowych pakietów jak NumPy lub Python Imaging Library martwienia się nazwy swoich modułów.
Załóżmy, że chce się zaprojektować zbiór modułów (,,pakiet'') służący do jednolitej obsługi plików i danych dźwiękowych. Istnieje mnóstwo formatów zapisu dźwięku (zwykle rozpoznawane po rozszerzeniu plików, np. .wav, .aiff, .au), co spowoduje, że może będziesz musiał stworzyć i utrzymywać zwiększającą się kolekcję modułów konwersji pomiędzy różnymi formatami plików. Jest również dużo różnych operacji, które można przeprowadzić na danych dźwiękowych (np. miksowanie, dodawanie pogłosu, zastosowanie funkcji equalizera, tworzenie sztucznego efektu stereo), tak więc, kończąc już, będziesz pisał niekończący się strumień modułów do wykonywania tych operacji. Poniżej przedstawiono jedną z możliwych struktur takiego pakietu (wyrażona ona jest w postaci hierarchicznego drzewa, na podobieństwo systemu plików):
Sound/ Pakiet szczytowy
__init__.py Inicjalizacja pakietu do obsługi dźwięku
Formats/ Moduły składowe do konwersji plików
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
Effects/ Pakiet składowy z efektami dźwiękowymi
__init__.py
echo.py
surround.py
reverse.py
...
Filters/ Pakiet składowy z operacjami filtrowania
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
__all__, opisaną później.
Użytkownicy tego pakietu mogą importować poszczególne moduły, np.:
import Sound.Effects.echo
Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)
from Sound.Effects import echo
echo.echofilter(input, output, delay=0.7, atten=4)
Inną wariacją na ten temat jest zaimportowanie wprost żądanej funkcji:
from Sound.Effects.echo import echofilter
W ten sposób ponownie ładujemy moduł składowy echo, lecz jego funkcja echofilter() jest dostępna wprost:
echofilter(input, output, delay=0.7, atten=4)
Zauważ, że kiedy używa się from pakiet import element,
element może być modułem składowym (lub pakietem składowym) lub inną nazwą
zdefiniowaną dla tego pakietu,, jak funkcja, klasa czy zmienna.
Instrukcja import najpierw sprawdza, czy element jest zdefiniowany w
pakiecie; jeśli nie, zakłada się, że jest to moduł i poczynione są starania o
jego załadowanie. Jeśli nie zostanie on znaleziony, zgłaszany jest wyjątek
ImportError.
W przeciwieństwie do tego, jeśli używa się składni import
element.element_skladowy.kolejny_element_skladowy, każdy element z
wyjątkiem ostatniego musi być pakietem: ostatni element może być modułem lub
pakietem ale nie klasą, funkcją lub zmienną zdefiniowaną w poprzednim
elemencie.
A teraz, co się stanie, kiedy użytkownicy napiszą from Sound.Effects
import *? Ktoś mógłby pomyśleć naiwnie, że ta instrukcja w jakiś sposób
wychodzi do systemu plików, znajduje wszystkie pliki z modułami składowymi,
które są obecne w pakiecie-katalogu i wszystkie je importuje. Niestety, taka
operacja nie działa zbyt dobrze na macintosh'ach i w Windows, gdzie system
plików nie zawsze wyposażony jest w dokładną informację na temat wielkości
liter w nazwach!6.9Na tych platformach nie ma sposobu dowiedzenia się, czy plik ECHO.PY
powien być zaimportowany jako moduł echo, Echo czy
ECHO (np. Windows 95 ma denerwujący zwyczaj pokazywania nazw plików z
pierwszą dużą literą). Ograniczenie DOS-a (8+3 znaki na nazwę pliku) dodaje
jeszcze jeden interesujący problem do tej listy jeżeli chodzi o długie nazwy
modułów.
Jedynym wyjściem dla autora takiego pakietu jest dostarczenie wprost indeksu
jego części składowych. Instrukcja importu posługuje się następującą konwencją:
jeżeli kod pakietu __init__.py zdefiniuje listę o nazwie __all__,
to przyjmuje się, że zawiera ona nazwy wszystkich modułów importowanych za
pomocą instrukcji from pakiet import *. Zadaniem autora pakietu
jest utrzymywanie stanu tej listy na bieżąco, w chwili gdy wypuszczane są nowe
wersje pakietu. Autorzy pakietów mogą również nie dostarczać tej listy, jeśli
nie widzą sensu z importowania * z ich pakietu. Na przykład plik
Sound/Effects/__init__.py mógłby zawierać następujący kod:
__all__ = ["echo", "surround", "reverse"]
Znaczyłoby to, że from Sound.Effects import * zaimportuje trzy moduły
składowe z pakietu Sound.
Jeśli __all__ nie jest zdefinowana, instrukcja from Sound.Effects
import * nie zaimportuje wszystkich modułów składowych z pakietu
Sound.Effects do bieżącej przestrzeni nazw: upewni się tylko, czy
pakiet Sound.Effects został zaimportowany (z możliwym wykonaniem kodu
z pliku __init__.py) a potem zaimportuje wszystkie nazwy zdefiniowane w
tym pakiecie. Wchodzą w nie nazwy zdefiniowane (i moduły składowe załadowane
wprost) w pliku __init__.py oraz moduły składowe pakietu załadowane
wprost przez poprzednie instrukcje importu, tzn.
import Sound.Effects.echo import Sound.Effects.surround from Sound.Effects import *
W tym przykładzie moduły echo i sorround importowane są do
bieżącej przestrzeni nazw ponieważ są zdefiniowane w pakiecie
Sound.Effects, gdy wykonywany jest from...import (działa to
również, gdy zdefiniowano __all__).
Trzeba tu zauważyć, że stosowanie importowania * z modułu lub pakietu idzie powoli w odstawkę, ponieważ często powoduje nieczytelny kod. Jest oczywiście w porządku, gdy stosuje się tę formułę, aby zaoszczędzić trochę na klepaniu klawiszami w trybie interaktywnym i gdy pewne moduły są zaprojektowane tak, że eksportują tylko nazwy odpowiadające pewnym schematom.
Trzeba pamiętać, że nie ma nic złego w używaniu formuły from Pakiet
import pewien_modul! Właściwie, ta notacja jest zalecana, chyba że moduł
importujący używa modułów składowych o takiej samej nazwie z paru różnych
pakietów.
Często zachodzi wymóg odniesienia się jednego modułu do drugiego. Na przykład,
moduł sorround może używać modułu echo. W rzeczywistości,
jest to tak często spotykane, że instrukcja import poszukuje najpierw w
zawierającym ją pakiecie, zanim przejdzie na standardową ścieżkę poszukiwań.
Tak więc, moduł sorround może użyć zwykłego import echo lub
from echo import echofilter. Jeśli importowany moduł nie zostanie
znaleziony w bieżącym pakiecie (w którym bieżący moduł jest modułem
składowym), instrukcja import szuka w szczytowym module o podanej
nazwie.
Kiedy pakiety posiadają składowe pakiety (tak jak Sound w naszym
przykładzie), nie istnieje skrót, aby odnieść się do modułu składowego
pakietów składowych -- trzeba użyć pełnej nazwy pakietu składowego. Na
przykład, jeśli moduł Sound.Filters.vocoder musi użyć modułu
echo z pakietu Sound.Effects, może zastosować from
Sound.Effects import echo.