Zapisz jako PDF

Transkrypt

Zapisz jako PDF
Spis treści
1 Moduły i biblioteki
1.1 Najprostszy moduł
1.2 Biblioteka standardowa
1.3 Funkcja dir
1.4 Jestem modułem, czy programem?
1.5 Paczki modułów
2 Ćwiczenia
Moduły i biblioteki
Wspomnieliśmy wcześniej, że problemu raz rozwiązanego nie warto rozwiązywać po raz drugi,
trzeci, ... (no chyba, że mamy pomysł na jakieś jakościowo nowe rozwiązanie). Zgodnie z tą zasadą,
kod stanowiący rozwiązanie opakowuje się w funkcję - z której następnie można korzystać
wielokrotnie. Ale na razie wiemy tylko, że z funkcji możemy korzystać w obrębie programu, w którym
występuje definicja tejże funkcji. A co z innymi programami? Metoda kopiuj/wklej to nie jest
najlepszy pomysł - wyobraźmy sobie chociaż, że w kodzie funkcji wykryliśmy drobny błąd (albo
możliwość istotnego ulepszenia); będziemy teraz wyszukiwać wszystkich programów, w których ten
kod uprzednio wkleiliśmy, aby je skorygować? Zamiast tego, lepiej jest skorzystać z stworzonego
dokładnie w tym celu mechanizmu modułów - plików, w których umieszczamy definicje funkcji (i
ewentualnie innych obiektów), z których będzie można korzystać w wielu różnych programach.
Ułatwienie wielokrotnego użytku kodu nie jest jedyną korzyścią z dzielenia kodu
programu na funkcje. Warto to robić również, gdy wielokrotnego użytku się nie
przewiduje - o ile zadanie do wykonania przez program nie jest trywialne proste, a kod je
realizujący bardzo krótki. Wprowadzenie do kodu pewnej struktury wynikającej z
podziału różnych elementów algorytmu pomiędzy funkcje sprzyja czytelności programu i
ułatwia jego ewentualną modyfikację w przyszłości.
Najprostszy moduł
Jako moduł może służyć dowolny plik zawierający kod w Pythonie, opatrzony nazwą z końcówką .py
(tutaj nazwa ma znaczenie). Zazwyczaj w module umieszcza się jedynie definicje (funkcji, klas,
ewent. stałych nazwanych), a nie - kod faktycznie wykonywany.
Nazwijmy plik o poniższej treści witaj.py:
#! /usr/bin/python3
def witaj(imie):
print('Witaj {}!'.format(imie))
Wykorzystaliśmy tu znaną już nam metodę format do zgrabnego wstawienia imienia do treści
powitania. Ten sam skutek dałoby się osiągnąć stosując operację sklejania napisów:
print('Witaj ' + imie + '!')
użycie formatowania jednak jest zalecane, zwłaszcza w bardziej złożonych przypadkach.
Uruchomienie pliku witaj.py jako programu nie spowoduje żadnego widocznego skutku - funkcja
witaj zostanie wprawdzie zdefiniowana, ale program zakończy działanie zanim zostanie ona w
ogóle użyta (wywołana). Chcąc wykorzystać tę funkcję w oddzielnym programie, musimy najpierw w
kodzie tego programu wskazać, gdzie znajduje się definicja tej funkcji. Do tego służy polecenie
import:
#! /usr/bin/python3
import witaj
witaj.witaj('Heleno')
Notacja witaj.witaj w tym przypadku wskazuje, że chodzi o funkcję witaj (słowo po kropce) z
modułu o nazwie witaj (to przed kropką). Oczywiście nazwy te równie dobrze mogą brzmieć różnie,
a w jednym module można zdefiniować wiele funkcji. Polecenie import witaj nadaje, w ramach
tego programu, znaczenie nazwie witaj - będzie ona oznaczać moduł, którego zawartością
(elementami) są funkcje (i ew. inne obiekty) zdefiniowane w pliku witaj.py.
Można również inaczej:
#! /usr/bin/python3
from witaj import witaj
witaj('Heleno')
Przy tej postaci instrukcji import, udostępniona w ramach programu zostaje tylko funkcja witaj i
należy się do niej odwoływać przez ,,gołą" nazwę. Obiektów importowanych z modułu o nazwie
wskazanej po słowie from może być więcej, należy podać ich nazwy po słowie import, oddzielone
przecinkami.
Można też jeszcze inaczej:
#! /usr/bin/python3
from witaj import *
witaj('Jakubie')
Taka instrukcja poleca udostępnić wszystkie nazwy, jakie zostały zdefiniowane w module witaj. W
tym akurat przypadku jest tylko jedna taka nazwa, nie dzieje się więc nic innego niż w poprzednim
przykładzie. Jeżeli jednak moduł witaj zostanie w przyszłości wzbogacony o dalsze definicje, to
używając instrukcji import z gwiazdką jak powyżej, będziemy te definicje importować do swojego
programu zupełnie nieświadomie; nie będzie w tym nic złego, dopóki się nie okaże np. że nazwa
któregoś z obiektów zdefiniowanych w tym module pokrywa się z jakąś nazwą występującą w
bibliotece standardowej, i to nazwą obiektu, z jakiego postanowiliśmy również skorzystać w naszym
kodzie - może się wtedy zdarzyć, że będziemy wywoływać wcale nie tę funkcję, o którą nam
chodziło... Więcej o możliwych konfliktach nazw powiemy dalej, na dziś warto zapamiętać:
instrukcja from ... import * nie powinna występować w ostatecznej wersji kodu żadnego
programu (nie ma nic złego w używaniu jej np. przy interakcyjnym testowaniu działania funkcji z
danego modułu, itp.).
Instrukcja import we wszystkich jej wersjach jest instrukcją Pythona jak każda inna; można ją np.
wywoływać warunkowo (wewnątrz instrukcji if, czy też wewnątrz definicji funkcji - w takim
przypadku, nazwy zaimportowane mają zasięg jedynie lokalny, ograniczony do wnętrza funkcji,
podobnie jak zmienne lokalne, wprowadzone wewnątrz definicji funkcji.
Biblioteka standardowa
Domyślna instalacja środowiska Python jest od razu zaopatrzona w dość bogatą kolekcję gotowych
modułów, zawierających rozwiązania problemów już dawno rozwiązanych i często przydatne
programiście. Biblioteka standardowa jest doskonale udokumentowana - wystarczy zajrzeć tutaj, i
powielanie tej dokumentacji nie miałoby sensu - przykłady zastosowań zobaczymy wkrótce.
Niekiedy rozwiązanie jakiegoś problemu wymaga sięgnięcia do kodu na ,,niższym poziomie" niż
Python, np. w języku C (lub też może być to po prostu opłacalne ze względów wydajnościowych).
Biblioteka standardowa zawiera również i takie moduły, obok modułów, których zawartością jest kod
w Pythonie. Moduły takie można też tworzyć samodzielnie, ale jest to temat spoza zakresu tego
kursu.
Korzystając z modułów biblioteki standardowej warto nieco uważać na możliwość konfliktów nazw;
nie należy np. własnemu programowi lub modułowi nadawać nazwy identycznej z nazwą któregoś z
modułów standardowych, z którego zamierzamy skorzystać w ramach danego projektu - dla
instrukcji import moduł własny programisty ma pierwszeństwo, i w efekcie moduł własny
,,przesłoni" standardowy. Ale na wszelki wypadek lepiej jest unikać wszystkich nazw modułów
standardowych (a nuż w trakcie rozwoju naszego projektu postanowimy wykorzystać w nim kolejne
moduły standardowe?).
Funkcja dir
Funkcję dir można wykorzystać do zbadania zawartości modułu:
In [1]: import witaj
In [2]: dir(witaj)
Out[2]:
['__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'witaj']
Wynikiem jest lista nazw zdefiniowanych w podanym module. Nazwy otoczone znakami podkreślenia
(podwójnymi) mają specjalne znaczenie i powstają ,,automatycznie"; nie powinniśmy sami definiować
nazw o zbliżonym kształcie - chyba że świadomie, i wiedząc dokładnie co chcemy tym osiągnąć.
Jestem modułem, czy programem?
Nazwa __name__ w module jest dość przydatna. Ponieważ każdy plik o nazwie kończącej się na .py
może pełnić zarówno rolę modułu, jak i programu wykonywalnego (,,głównego"), to dobrze jest, aby
w kodzie zawartym w tym pliku można było rozpoznać, w jakiej roli został on uruchomiony. Jeżeli
plik wykorzystywany jest w charakterze modułu, tj. poprzez instrukcję import, to:
In [4]: witaj.__name__ == 'witaj'
Out[4]: True
czyli pod nazwą __name__ kryje się napis, będący nazwą modułu. Jeżeli jednak plik został
uruchomiony w charakterze programu głównego, to treścią tej nazwy będzie napis '__main__'. Jest
szeroko przyjętą praktyką umieszczania poleceń, które mają być wykonywane tylko w przypadku,
gdy plik zostanie uruchomiony jako program główny, wewnątrz instrukcji if:
(...)
if __name__ == '__main__':
# blok instrukcji uruchamiających program
Pozwala to na wykorzystywanie tego samego pliku w obu rolach: programu głównego, i modułu.
Paczki modułów
Moduły mogą mieć strukturę wielopoziomową - wtedy mówimy o paczkach. Inaczej mówiąc, paczka
jest obiektem, zawierającym w sobie moduły - lub kolejne paczki, ... itd. aż do poziomu modułów,
które już zawierają definicje funkcji i/lub innych obiektów (klas, itp.).
# można importować moduły podając pełną "drogę" do nich
import paczka.modul1
import paczka.modul2
# to importuje nazwy paczka.modul1, paczka.modul2
# lub, jeśli wolimy:
from paczka import modul1, modul1
# w tym przypadku zaimportowaliśmy moduły pod "krótkimi" nazwami: modul1,
modul2
# albo możemy sięgnąć po konkretne funkcje, itp:
from paczka.modul1 import pewna_funkcja
Struktura paczek zawierających moduły odpowiada strukturze folderów na dysku zawierających
odpowiednie pliki .py. Szczegóły w dokumentacji.
Ćwiczenia
poprzednie | strona główna | dalej
RobertJB (dyskusja) 14:51, 14 lip 2016 (CEST)

Podobne dokumenty