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)