PPy3/Moduły: Różnice pomiędzy wersjami

Z Brain-wiki
(Utworzono nową stronę "=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...")
 
Linia 48: Linia 48:
 
</source>
 
</source>
  
Przy tej postaci instrukcji <tt>import</tt>, udostępniona w ramach programu zostaje tylko funkcja <tt>witaj</tt> i należy się do niej odwoływać przez ,,gołą" nazwę. Obiektów importowanych z modułu o nazwie wskazanej po słowie <tt>from</tt> może być więcej, należy podać ich nazwy po słowie <tt>import</tt>, oddzielone przecinkami.
+
Przy tej postaci instrukcji <tt>import</tt>, udostępniona w ramach programu zostaje tylko funkcja <tt>witaj</tt> i należy się do niej odwoływać przez ,,gołą" nazwę. Obiektów importowanych z modułu o nazwie wskazanej po słowie <tt>from</tt> może być więcej, należy podać ich nazwy po słowie <tt>import</tt>, oddzielone przecinkami.
  
 +
Można też jeszcze inaczej:
 +
<source lang=python>
 +
#! /usr/bin/python3
 +
 +
from witaj import *
 +
 +
witaj('Jakubie')
 +
 +
</source>
 +
 +
Taka instrukcja poleca udostępnić ''wszystkie'' nazwy, jakie zostały zdefiniowane w module <tt>witaj</tt>. 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ł <tt>witaj</tt> zostanie w przyszłości wzbogacony o dalsze definicje, to używając instrukcji <tt>import</tt> 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 <tt>from ... import *</tt> 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.).
  
 
=Ćwiczenia=
 
=Ćwiczenia=

Wersja z 12:46, 3 sie 2016

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.).

Ćwiczenia


poprzednie | strona główna | dalej

RobertJB (dyskusja) 14:51, 14 lip 2016 (CEST)