Zapisz jako PDF

Transkrypt

Zapisz jako PDF
Spis treści
1 Wprowadzenie
1.1 Jak to działa?
2 Pliki pośrednie .pyc
3 Konstrukcja from ... import ...
4 Konstrukcja import ... as ...
5 Samoidentyfikacja modułu
5.1 Jak to działa?
6 Tworzenie własnych modułów
6.1 Jak to działa?
7 Funkcja dir
7.1 Jak to działa?
8 Paczki
9 Podsumowanie
10 Zadania
10.1 Liczby Fibonacciego
Wprowadzenie
Dowiedziałeś się, jak używać wielokrotnie fragmentu kodu programu dzieląc go na funkcje. A w jaki
sposób można używać funkcji zdefiniowanych w innym miejscu? Jak pewnie zgadłeś, odpowiedzią są
moduły.
Są różne metody pisania modułów, ale najprościej jest stworzyć plik z rozszerzeniem .py, który
będzie zawierał funkcje i zmienne.
Moduły do Pythona można pisać nie tylko w Pythonie. Można, na przykład, napisać moduł do
wydajnych obliczeń numerycznych w bardziej wydajnym języku C i po skompilowaniu używać go w
swoim pythonowym kodzie.
Aby użyć zawartości modułu, należy go zaimportować. Dotyczy to również modułów ze standardowej
biblioteki Pythona, od czego właśnie zaczniemy.
Przykład:
#!/usr/bin/env python
# -*- coding: utf-8 -*# Nazwa pliku: uzycie_sys.py
import sys
print 'Polecenia linii komend to:'
for i in sys.argv:
print i
print '\n\nPYTHONPATH to:',sys.path,'\n'
Rezultat:
$ python uzycie_sys.py my jestesmy argumentami
Polecenia linii komend to:
uzycie_sys.py
my
jestesmy
argumentami
PYTHONPATH to: ['/home/Swaroop', '/usr/lib/python25.zip',
'/usr/lib/python2.5',
'/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk',
'/usr/lib/python2
.5/lib-dynload', '/usr/local/lib/python2.5/site-packages',
'/usr/lib/python2.5/s
ite-packages', '/usr/lib/python2.5/site-packages/Numeric',
'/usr/lib/python2.5/s
ite-packages/PIL', '/usr/lib/python2.5/site-packages/gst-0.10',
'/var/lib/python
-support/python2.5', '/usr/lib/python2.5/site-packages/gtk-2.0',
'/var/lib/pytho
n-support/python2.5/gtk-2.0']
PYTHONPATH to lista katalogów, w których Python poszukuje modułów. W IDLE listę taką można
obejrzeć klikając: File->Path Browser.
Jak to działa?
Najpierw importujemy moduł sys używając polecenia import sys, czyli mówimy Pythonowi, że
chcemy go używać. Moduł sys zawiera polecenia związane z Pythonem i jego środowiskiem, czyli
systemem.
Podczas wykonywania polecenia import sys Python szuka pliku lub katalogu o odpowiedniej
nazwie (m.in. zaczynającej się od sys). Aby operacja się powiodła, moduł musi być w jednym z
katalogów wymienionych w zmiennej sys.path.
Po znalezieniu modułu treść jego głównego bloku zostaje wykonana, a funkcjonalność dostarczana
przez moduł staje się dostępna w programie. Opisana inicjalizacja modułu następuje tylko raz,
podczas jego pierwszego importu w danym programie.
Do zmiennych i funkcji zdefiniowanych w module dostajemy się korzystając z notacji z kropką. Na
przykład, zmienna argv w module sys jest dostępna jako (sys.argv), dzięki czemu wiadomo, że ta
nazwa jest częścią modułu sys. Zaletą tej notacji jest możliwość zdefiniowania zmiennych o tej
samej nazwie w różnych modułach bez utraty jednoznaczności. Możemy mieć wiele zmiennych argv
w różnych modułach, i jednoznacznie się do niech odwoływać.
Zmienna sys.argv jest listą ciągów znaków. (Listy poznamy dokładniej w następnym rozdziale.)
Dokładniej mówiąc, zawiera listę argumentów, z którymi program został wywołany, czyli nazwę pliku
zawierającego program oraz to, co użytkownik programu wpisał po nazwie w wywołaniu z wiersza
poleceń.
Gdy wpisujemy python uzycie_sys.py my jestesmy argumentami, uruchamiamy moduł
uzycie_sys.py za pomocą aplikacji python wraz z argumentami my jestesmy argumentami.
Python przechowuje dla nas treść linii komend w zmiennej sys.argv.
Pamiętaj, że nazwa uruchamianego skryptu jest zawsze na początku listy sys.argv. Dlatego w
omawianym przykładzie mamy następujące przypisania:
uzycie_sys.py jako sys.argv[0],
my jako sys.argv[1],
jestesmy jako sys.argv[2]
argumentami jako sys.argv[3].
Zauważ, że Python numeruje od 0, nie od 1.
sys.path zawiera listę katalogów, z których są importowane moduły. Zobacz, że pierwsza pozycja
to folder, w którym został uruchomiony program. Folder, w którym został uruchomiony program
zostaje automatycznie wstawiony na początek listy, natomiast pozostałe jej elementy są takie same
niezależnie od miejsca wywołania. Oznacza to, że możesz łatwo importować moduły znajdujące się w
katalogu bieżącym. Inne moduły są dostępne tylko w wypadku gdy znajdują się w którymś z
katalogów wymienionych w ścieżce.
Przy okazji, możesz w każdej chwili podejrzeć katalog, w którym jesteś wpisując w Pythonie print
os.getcwd() (oczywiście najpierw musisz zaimportować moduł os).
Pliki pośrednie .pyc
Importowanie modułu to dosyć czasochłonna operacja, więc Python używa pewnych sztuczek, aby ją
przyspieszyć. Jedną z nich jest tworzenie plików skompilowanych do kodu bajtowego — pewnej
formy pośredniej z rozszerzeniem .pyc. Pliki .pyc są niezależne od platformy. Plik .pyc jest
przydatny, gdy masz zamiar zaimportować dany moduł po raz kolejny, używając innego programu - o
wiele szybciej, gdyż część pracy potrzebnej do zaimportowania została już wykonana.
Uwaga
Pliki .pyc są zazwyczaj tworzone w tym samym folderze, co odpowiednie pliki .py. Jeżeli
Python nie ma pozwolenia na zapis w tym folderze, pliki .pyc nie zostaną utworzone.
Konstrukcja from ... import ...
Jeżeli chcesz bezpośrednio zaimportować zmienną argv do swojego programu (aby nie pisać ciągle
sys.), możesz użyć wyrażenia from sys import argv. Jeżeli chcesz zaimportować wszystko, co
znajduje się w module sys, możesz użyć wyrażenia from sys import *. To działa z każdym
modułem.
Tak naprawdę, powinieneś normalnie używać formy import ..., i odwoływać się do zmiennych z
innych modułów przez nazwę ich modułu. Formy from...import... powinieneś używać wtedy,
gdy dana nazwa będzie używana bardzo często i kłopotliwe byłoby używanie pełnej ścieżki. Formy z
gwiazdką nie powinieneś używać w programach, bo powoduje zaśmiecenie przestrzeni nazw.
Niemniej jest ona użyteczna w trybie interaktywnym, gdzie naprawdę nie chcemy pisać długich
nazw.
Konstrukcja import ... as ...
Istnieje też możliwość zaimportowania modułu pod inną nazwę. Konstrukcja import nazwa_modulu
as inna_nazwa spowoduje zaimportowanie modułu, z tym, że dostęp do jego zmiennych i funkcji
będzie się odbywał przez inna_nazwa. . Może to być przydatne jeśli chcemy sobie oszczędzić
pisania (na ogół inna_nazwa wybierana jest jako znacznie krótsza niż oryginalna nazwa_modulu)
Samoidentyfikacja modułu
Każdy moduł posiada zmienną zawierającą jego nazwę (zazwyczaj). Najczęściej używa się tej
zmiennej wtedy, gdy chcemy się dowiedzieć, czy moduł został zaimportowany, czy uruchomiony jako
program. Jak już wcześniej wspomniano, gdy moduł zostaje zaimportowany po raz pierwszy, jego kod
zostaje wykonany. W przypadku definicji funkcji i klas ich wykonanie oznacza po prostu
zdefiniowanie tych funkcji i klas. Polecenia zapisane w treści funkcji nie zostają wykonane w
momencie definicji funkcji, lecz dopiero później, w momencie wywołania funkcji. Podobnie jest dla
klas, czyli definicja klasy nie powoduje stworzenia obiektu. Natomiast wyrażenia znajdujące się poza
definicjami funkcji i klasy zostają wykonane od razu. Często chcemy, by zostałe one wykonane tylko
wtedy, gdy uruchamiamy moduł jako program.
Zmienna __name__ zawiera nazwę modułu. Wyjątkiem jest sytuacja gdy został on uruchomiony
samodzielnie, jako program. Wówczas zawiera napis '__main__'. Dzięki temu możemy rozróżnić
dwa sposoby wywołania modułu i podjąć odpowiednie decyzje.
Przykład:
#!/usr/bin/env python
# -*- coding: utf-8 -*# Nazwa pliku: nazwa.py
if __name__ == '__main__':
print 'Ten program jest uruchomiony samodzielnie.'
else:
print 'Zostałem zaimportowany z innego modułu.'
Rezultat:
Niepoprawny język.
Musisz wybrać język w następujący sposób: <source lang="html4strict">...</source>
Języki obsługiwane w podświetlaniu składni:
4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript,
actionscript3, ada, algol68, apache, applescript, arm, asm, asp, asymptote,
autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf,
bibtex, blitzbasic, bnf, boo, c, caddcl, cadlisp, cfdg, cfm, chaiscript, cil,
clojure, cmake, cobol, coffeescript, cpp, csharp, css, cuesheet, d, dcl, dcpu16,
dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang,
euphoria, f1, falcon, fo, fortran, freebasic, freeswitch, fsharp, gambas, gdb,
genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, haxe,
hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java,
java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, ldif, lisp, llvm,
locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua,
m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml,
mysql, nagios, netrexx, newlisp, nsis, oberon2, objc, objeck, ocaml, octave, oobas,
oorexx, oracle11, oracle8, oxygene, oz, parasail, parigp, pascal, pcre, per, perl,
perl6, pf, php, pic16, pike, pixelbender, pli, plsql, postgresql, povray,
powerbuilder, powershell, proftpd, progress, prolog, properties, providex,
purebasic, pycon, pys60, python, q, qbasic, rails, rebol, reg, rexx, robots,
rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty,
spark, sparql, sql, stonescript, systemverilog, tcl, teraterm, text, thinbasic,
tsql, typoscript, unicon, upc, urbi, uscript, vala, vb, vbnet, vedit, verilog, vhdl,
vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xpp,
yaml, z80, zxbasic
$ python nazwa.py
Ten program jest uruchomiony samodzielnie.
$ python
>>> import nazwa
Zostałem zaimportowany z innego modułu.
>>>
Jak to działa?
Każdy moduł Pythona ma zdefiniowaną własną nazwę. Jeżeli jest nią '__main__', oznacza to, że
moduł działa samodzielnie, a wtedy możemy podjąć odpowiednie działania.
Tworzenie własnych modułów
Tworzenie własnych modułów jest proste, robisz to cały czas! A to dlatego, że każdy program w
Pythonie jest także modułem. Ty musisz tylko zadbać, żeby miał rozszerzenie .py. Ten przykład
powinien wszystko wyjaśnić.
Przykład:
#!/usr/bin/env python
# -*- coding: utf-8 -*# Nazwa pliku: mojmodul.py
def mowczesc():
print 'Cześć, tu mówi mojmodul.'
__version__ = '0.1'
# Koniec modułu mojmodul.py.
Oto przykładowy moduł. Jak widać, nie ma tu nic szczególnie różniącego go od zwykłego programu w
Pythonie. Następnie zobaczymy, jak go użyć w innych naszych programach.
Pamiętaj, że moduł powinien być umieszczony w tym samym katalogu co program, który z niego
korzysta, lub też w jednym z katalogów wpisanych w sys.path.
#!/usr/bin/env python
# -*- coding: utf-8 -*# Nazwa pliku: mojmodul_demo.py
import mojmodul
mojmodul.mowczesc()
print 'Wersja', mojmodul.__version__
Rezultat:
$ python mojmodul_demo.py
Cześć, tu mówi mojmodul.
Wersja 0.1
Jak to działa?
Zauważ, że używamy tego samego zapisu z kropkami przy uzyskiwaniu dostępu do elementów
modułu. Python robi dobry użytek z tej samej notacji nadając temu swoisty „pythonowy” styl, dzięki
czemu nie musimy wciąż poznawać coraz to nowych metod pracy.
Oto wersja z użyciem from...import...:
#!/usr/bin/env python
# -*- coding: utf-8 -*# Nazwa pliku: mojmodul_demo2.py
from mojmodul import mowczesc, __version__
mowczesc()
print 'Wersja', __version__
Rezultat mojmodul_demo2.py jest taki sam jak mojmodul_demo.py.
Ta forma jest przykładem bardzo złego stylu. Zauważ, że jeżeli nazwa __version__ już istniała
wcześniej w module, który importuje mojmodul, powstanie konflikt nazw. Na dodatek jest to bardzo
prawdopodobne, ponieważ zmienna o nazwie __version__ jest standardowo używana po
przechowywania wersji modułu. W momencie kiedy plik mojmodul_demo zostanie wydłużony, łatwo
o pomyłkę, bo normalnie __version__ to wersja bieżącego modułu, a tutaj to wersja modułu
mojmodul. Stąd zawsze lepiej użyć wyrażenia import w taki sposób, by ograniczyć liczbę
importowanych nazw.
Możesz także użyć:
from mojmodul import *
To spowoduje zaimportowanie prawie wszystkich nazw, jak na przykład mowczesc, ale ominie
__version__, gdyż zaczyna się ona od podwójnego podkreślenia. Ta wersja jest jeszcze brzydsza.
Funkcja dir
Możesz użyć wbudowanej funkcji dir, aby wypisać nazwy zdefiniowane w pewnym obiekcie. Na
przykład w module takie nazwy wskazują na funkcje, klasy i zmienne w nim zadeklarowane.
Gdy dir() zostaje wywołane z argumentem, to działa na nim. W wypadku wywołania dir() bez
argumentu, działa ono na przestrzeni nazw, z której została wywołana.
Przykład:
$ python
>>> import sys # Zdobądź listę atrybutów, w tym wypadku dla modułu sys.
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__',
'__s
tderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames',
'_g
etframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder',
'call_trac
ing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode',
'exc_clear
', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit',
'f
lags', 'float_info', 'getcheckinterval', 'getdefaultencoding',
'getdlopenflags',
'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount',
'get
sizeof', 'gettrace', 'hexversion', 'maxint', 'maxsize', 'maxunicode',
'meta_path
', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform',
'prefix',
'ps1', 'ps2', 'py3kwarning', 'pydebug', 'setcheckinterval',
'setdlopenflags', '
setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
'subv
ersion', 'version', 'version_info', 'warnoptions']
>>> dir() # Zdobądź listę atrybutów dla aktualnego modułu.
['__builtins__', '__doc__', '__name__', '__package__', 'sys']
>>> a = 5 # Stwórz nową zmienną "a".
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a', 'sys']
>>> del a # Usuń nazwę.
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'sys']
>>>
Jak to działa?
Na początku sprawdzamy działanie dir na zaimportowanym module sys. Widać długą listę jego
atrybutów.
Następnie używamy funkcji dir bez parametrów. Domyślnie zwraca ona listę atrybutów aktualnego
modułu. Zauważ, że lista zaimportowanych modułów jest też częścią wyniku.
W celu ujrzenia dir w akcji, deklarujmy nową zmienną a, przypisujemy jej wartość, a następnie
sprawdzamy, że na liście pojawiła nazwa naszej nowej zmiennej. Usuwamy ją poleceniem del, czego
efekt widać po kolejnym użyciu dir.
Uwaga do del — to polecenie usuwa zmienną/nazwę (w tym wypadku del a), w efekcie później nie
da się odnieść do tej nazwy, tak jakby nigdy wcześniej nie istniała.
Pamiętaj, że funkcja dir() działa z każdym obiektem. Na przykład możesz napisać dir(max), aby
poznać atrybuty funkcji max, albo dir(str), aby poznać atrybuty klasy str.
Paczki
Właśnie zacząłeś dogłębnie poznawać hierarchię elementów twoich programów. Zmienne zazwyczaj
znajdują się w funkcjach. Funkcje oraz zmienne globalne — w modułach. A co gdy chcesz zarządzać
modułami? W tym miejscu na scenę wkraczają paczki.
Paczki to katalogi z modułami oraz ze specjalnym plikiem __init__.py, który informuje Pythona,
że ten katalog jest specjalnie przeznaczony właśnie do przechowywania modułów.
Powiedzmy, że chcesz stworzyć paczkę o nazwie swiat zawierającą paczki azja, afryka itd., zaś w
nich na przykład indie czy madagaskar.
Oto, jak powinna wyglądać twoja struktura katalogów:
jakiś katalog wymieniony w sys.path
└── swiat/
├── __init__.py
├── azja/
│
├── __init__.py
│
├── indie.py
│
└── chiny.py
└── afryka/
├── __init__.py
└── madagaskar.py
Paczki są wygodnym sposobem segregacji modułów. Zobaczysz wiele przykładów ich użycia w
[[../Biblioteka standardowa/|bibliotece standardowej]].
Podsumowanie
Tak jak funkcje są częściami programu wielokrotnego użytku, tak moduły to programy wielokrotnego
użytku. Paczki są odrębną hierarchią organizacji modułów. Standardowa biblioteka Pythona jest
przykładem zestawu paczek i modułów.
Zobaczyliśmy jak użyć tych modułów i utworzyć swoje własne.
Następnie poznamy pewne interesujące koncepty zwane strukturami danych.
Zadania
Liczby Fibonacciego
Stwórz moduł fib3 zawierający trzy funkcje zwracające -tą liczbę Fibonacciego — obliczoną
rekurencyjnie z definicji, w pętli, oraz ze wzoru Bineta. Sam moduł oraz funkcje muszą mieć
docstringi.
Moduł ma też zawierać bezargumentową funkcję test, której zadaniem jest sprawdzenie
poprawności działania wszystkich trzech funkcji i wypisanie odpowiedniego komunikatu. Test
powinien być wykonany dla pewnych ustalonych wartości, w szczególności tych granicznych, czyli 0,
1, 2 i innych. Przydatna może być ich lista na http://pl.wikisource.org/wiki/Ciąg_Fibonacciego.
Następnie napisz moduł fib3-czas, który wykorzystuje moduł fib3 i moduł time aby porównać
szybkość wykonywania wszystkich trzech algorytmów. Wynik powienien zostać wypisany w postaci
tabelki
n
1
2
...
T1/ms
0.5
0.5
...
T2/ms
0.3
0.5
...
T3/ms
0.7
1.0
...

Podobne dokumenty