Spotkania z Pythonem - Czesc 2 - organizacja projektu i obiektowosc

advertisement
Spotkania z Pythonem
Cz¦±¢ 2 - organizacja projektu i obiektowo±¢
Michaª Alichniewicz
Studenckie Koªo Automatyków SKALP
Gda«sk 2014
Dzi¦kuj¦ za uwag¦!
Na licencji Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.
M. Alichniewicz (SKALP)
Python vol. 2
2014
1 / 40
Organizacja plików
M. Alichniewicz (SKALP)
Python vol. 2
2014
2 / 40
Jak Python zapisuje pliki
Jedn¡ z zalet pythona jest wªa±nie fakt, »e posiada interaktywn¡ konsol¦.
Jednak - b¡d¹ co b¡d¹ - pisanie w niej jakiego± wi¦kszego programu raczej
do najwygodniejszych nie nale»y, nie wspominaj¡c o fakcie, »e czasami
chcemy program zapisa¢.
Python zapisuje pliki w formacie *.py. S¡ to zwykªe pliki tekstowe,
posiadaj¡ce wewn¡trz kod który normalnie by±my zapisywali. Ogólnie
przyj¦ªo si¦, »e plik powinien (chocia» nie musi)
zaczyna¢ si¦ wielolinijkowym komentarzem - tzw. docstringiem - pomaga
to w identykacji pliku, b¡d¹ te» tworzeniu dokumentacji. Taki plik
zwyczajowo jest zwany moduªem (ang. module)
M. Alichniewicz (SKALP)
Python vol. 2
2014
3 / 40
Jak Python zapisuje pliki
Jak uruchomi¢ taki plik? Najªatwiejszy sposób, to w konsoli systemu (nie
Pythona!) wpisa¢ polecenie typu
$ python ./moj_plik.py
W trakcie pracy z Pythonem pewnie te» zauwa»ycie »e w folderze z
Waszymi plikami *.py pojawi¡ si¦ tak»e takie pliki jak *.pyc i *.pyo - to
s¡ pliki skompilowane do kodu po±redniego - takie pliki równie» mo»emy
uruchamia¢.
M. Alichniewicz (SKALP)
Python vol. 2
2014
4 / 40
Šadowanie innych bibliotek
Póki co, do tej pory korzystali±my z biblioteki wbudowanej, tzw. builtin.
Jednak siª¡ Pythona s¡ biblioteki - istniej¡ biblioteki do obsªugi poª¡cze«
sieciowych, obróbki gracznej, oblicze« in»ynierskich i symulacji, baz
danych, i wiele, wiele innych.
Troch¦ z teorii programowania: ka»dy kompilowany (w naszym przypadku,
interpretowany), plik, operuje w tzw. przestrzeni nazw (ang. namespace).
Owa przestrze« nazw to abstrakcyjny zbiór etykiet wszelkich elementów
jakie mamy i jakich mo»emy u»y¢. W tej przestrzeni l¡duj¡ wszystkie
zmienne, funkcje i klasy jakie zdeniujemy.
M. Alichniewicz (SKALP)
Python vol. 2
2014
5 / 40
Šadowanie innych bibliotek
Poj¦cie przestrzeni nazw wyst¦puje generalnie w ka»dym j¦zyku
programowania. Zasada jest prosta: etykieta jest w przestrzeni nazw,
mo»emy j¡ u»y¢.
Dla przykªadu w C rozszerzali±my t¡ przestrze« o nowe symbole doª¡czaj¡c
plik nagªówkowy, np.
#include <stdio.h>
Jakby kto± zajrzaª do tego pliku, to tam s¡ denicje typów i tzw. prototypy
funkcji, które sªu»¡ gªównie po to »eby kompilator wiedziaª co ma do
dyspozycji - dyrektywa include wstawia tre±¢ pliku w swoje miejsce.
Doª¡czaniem pó¹niej wªa±ciwych kodów pod etykiety zajmuje si¦ linker.
M. Alichniewicz (SKALP)
Python vol. 2
2014
6 / 40
Šadowanie innych bibliotek
W Pythonie, nie ma jako takiej funkcji doª¡czania plików. Jest za to
funkcja importowania symboli. Python daje jednak nieco wi¦ksze
mo»liwo±ci w importowaniu ni» include w C - bo mo»emy
zaimportowa¢ caªy moduª (i odwoªywa¢ si¦ do moduªu, a wewn¡trz moduªu
do dalszych funkcji), albo zaimportowa¢ wybrane symbole z moduªu (czyli
mo»emy np. zaimportowa¢ tylko jedn¡ funkcj¦ z dost¦pnych 30)
Najprostszy import moduªu wygl¡da nast¦puj¡co:
# Zaimportuj modul - od tej pory mozna
# w kodzie sie odwolywac do modulu
# nazwa_modulu.
import nazwa_modulu
Do elementów tak zaimportowanego moduªu, dostaniemy si¦ przez
operator kropki:
# Wywolanie funkcji ``funkcja'' z modulu ``nazwa_modulu''
nazwa_modulu.funkcja()
M. Alichniewicz (SKALP)
Python vol. 2
2014
7 / 40
Šadowanie innych bibliotek
Przykªad praktyczny - wy±wietlanie czasu
import time
# Zaimportowanie modulu ``time''
print time.time()
#
#
#
#
print time.ctime() #
#
M. Alichniewicz (SKALP)
Tzw. UNIX timestamp
czyli liczba sekund liczona od
1 stycznia 1970 00:00,
czyli ``ery unixa''
Aktualna data i czas w
formie ``human friendly''
Python vol. 2
2014
8 / 40
Šadowanie innych bibliotek
Mo»emy równie» zaimportowa¢ konkretne elementy z moduªu, za pomoc¡
instrukcji from . . . import . . . , zwyczajowo umieszczanej na pocz¡tku
pliku, chocia» teoretycznie mo»na j¡ u»y¢ w dowolnym momencie:
# Z ``moj_modul'' zaimportuj ``funkcja1'', ``funkcja2''
from moj_modul import funkcja1, funkcja2
# Teraz mozemy sie odwolywac bezposrednio do funkcji
# bez korzystania z ``modulu nadrzednego'':
funkcja1()
funkcja2()
Istnieje równie» tzw. wild import, czyli import z danego moduªu
wszystkich symboli:
# Z ``moj_modul'' zaimportuj wszystko
from moj_modul import *
Jest to jednak konstrukcja skrajnie niezalecana.
M. Alichniewicz (SKALP)
Python vol. 2
2014
9 / 40
Šadowanie innych bibliotek
W stosunku do include z C, importowanie moduªów w Pythonie ró»ni si¦ w
jednej zasadniczej rzeczy. O ile include tylko doª¡cza tre±¢, która jest
nast¦pnie kompilowana, o tyle polecenie import w Pythonie powoduje
wykonanie moduªu! Trzeba o tym pami¦ta¢, zwªaszcza je»eli
importujemy moduª, który oprócz denicji funkcji/klas ma jeszcze
jak¡± logik¦ która to np. testuje (jakie± print nie obj¦te funkcj¡, etc.). Jak
to zobrazowa¢? Na przykªad tak:
import this
M. Alichniewicz (SKALP)
Python vol. 2
2014
10 / 40
Šadowanie innych bibliotek
Jak wi¦c zapobiec takiemu niechcianemu wykoniu? Mo»emy przenie±¢ kod
testuj¡cy do innego moduªu. Problem si¦ pojawi, gdy np. do takiego kodu
b¦dziemy chcieli wygenerowa¢ dokumentacj¦ - bo wi¦kszo±¢ generatorów
zwyczajnie doª¡cza te pliki przez import i wyci¡ga z nich docstringi.
Chc¦ testowa¢, co robi¢, jak »y¢? Wró¢my tutaj do poj¦cia przestrzeni
nazw. Przestrzenie nie s¡ anonimowe - maj¡ swoj¡ nazw¦. I tak, zazwyczaj
nasz namespace nazywa si¦ maªo wiele tak samo jak nasz moduª (je»eli jest
importowany). Jest za to jeden wyj¡tek - w gªównym pliku - czyli tym, co
jest bezpo±rednio podany na interpreter Pythona - ta przestrze« ma
specjaln¡ nazw¦ __main__.
M. Alichniewicz (SKALP)
Python vol. 2
2014
11 / 40
Šadowanie innych bibliotek
Jak wi¦c na to zareagowa¢? I to twórcy (twórca) Pythona przewidzieli.
Do naszej dyspozycji jest jedna specjalna zmienna która zawiera nazw¦
naszej przestrzeni nazw: __name__. Wi¦c mo»emy sprawdzi¢ jej
nazw¦. W efekcie dochodzimy do tego jak wygl¡da szkielet wi¦kszo±ci
moduªów Pythona:
"""
Docstring pliku / modulu
"""
import moj_modul # Importy
from moj_modul_2 import funkcja
# Kod funkcji / klas
if __name__ == "__main__":
# Kod wykonywany przy bezposrednim wywolaniu
M. Alichniewicz (SKALP)
Python vol. 2
2014
12 / 40
Šadowanie innych bibliotek
Dlaczego nie zaleca si¦ u»ywa¢ wild import'u?
Odpowied¹ jest stosunkowo prosta. Wild import zaimportuje wszystkie
symbole jakie s¡ dost¦pne w danym pliku, a w zasadzie przestrzeni nazw. A
wi¦c tak»e te» wszysktie symbole które tam zostaªy zaimportowane. Wi¦c
je»eli dla przykªadu, w pliku moj_modul.py mamy konstrukcj¦
import time
a w innym pliku, np moj_modul2.py wpiszemy
from moj_modul import *
to oka»e si¦, »e w tym drugim pliku mamy dost¦p do moduªu time. A
przecie» nigdzie go nie importowali±my! Korzystaj¡c z wild import nie
mamy kontroli nad tym co importujemy, o czym nale»y pami¦ta¢!
M. Alichniewicz (SKALP)
Python vol. 2
2014
13 / 40
Organizacja kodu w folderach
Przy wi¦kszych projektach, bardzo szybko dojdziemy do wniosku, »e
trzymanie kilkudziesi¦ciu plików w jednym folderze to nie najlepszy pomysª
(to nie system dla PKW). Intuicja mówi, »e mo»na to podzieli¢ na foldery.
Mo»emy by¢ jednak pewni, »e jak przeniesiemy moduª moj_modul.py do
folderu moj_folder spowoduje ze zwykªe
import moj_modul
raczej nie zadziaªa. Musimy Pythona poinformowa¢, »e to gdzie± le»y.
M. Alichniewicz (SKALP)
Python vol. 2
2014
14 / 40
Organizacja kodu w folderach
Jak ju» wiemy, w Pythonie funkcje/klasy organizujemy w moduªy. Jak z
kolei zorganizowa¢ grup¦ moduªów? Odpowied¹ brzmi: w paczk¦ (ang.
package).
Paczka to nic innego jak folder zawieraj¡cy moduªy. Wrzucenie wszystkiego
do folderu jednak nie wystarczy - Python musi zosta¢ poinformowany »e
dany folder to paczka. Robi si¦ to w stosunkowo prosty sposób - w folderze
nale»y umie±ci¢ plik o nazwie __init__.py. Co wa»ne, mo»e to
by¢ plik pusty, ale musi istnie¢.
Generalnie jest to plik który jest wykonywany przy importowaniu dowolnego
moduªu z paczki - i jest wykonywany PRZED wykonaniem importowanego
moduªu. Podobniej jak moduª, mo»e zawiera¢ docstring - wtedy dotyczy
on peªnej paczki.
M. Alichniewicz (SKALP)
Python vol. 2
2014
15 / 40
Organizacja kodu w folderach
No dobra, kod w paczkach jest - jak si¦ do niego dobra¢? Sposób jest
ju» znany - dyrektyw¡ import (oraz from . . . import . . . ).
Tu trzeba wspomnie¢ o jednym - teoretycznie mo»emy
zaimportowa¢ paczk¦ jako element (czyli import paczka), ale generalnie
wiele z tego nie dostaniemy. Powinni±my deniowa¢ wprost, co chcemy
zaimportowa¢, np.
import paczka.modul
# albo
from paczka import modul2
W 1 przypadku do elementów moduªu mo»emy si¦ odwoªa¢ przez
paczka.modul.element, z kolei w drugim od razu przez modul2.element.
M. Alichniewicz (SKALP)
Python vol. 2
2014
16 / 40
Obiektowo±¢ w Pythonie
M. Alichniewicz (SKALP)
Python vol. 2
2014
17 / 40
Denicja klasy
Python, chyba jak ka»dy wzgl¦dnie nowoczesny j¦zyk programowania,
wspiera obiektowo±¢. Jak obiektowo±¢, to i pojawia si¦ poj¦cie klasy. W
Pythonie denicja klasy do zaskakuj¡cych nie nale»y:
class Klasa():
"""
Docstring dla klasy
"""
# Kod klasy - jak pusta, to pass
pass
Instancj¦ takiej klasy tworzymy w prosty sposób:
instancja = Klasa()
M. Alichniewicz (SKALP)
Python vol. 2
2014
18 / 40
Denicja klasy
Typowe dla obiektowo±ci dziedziczenie, równie» istnieje:
class Klasa2(Klasa_rodzic, Klasa_rodzic2, ...):
"""
Docstring dla klasy
"""
# Kod klasy - jak pusta, to pass
pass
Jak wida¢ - mo»emy dziedziczy¢ z wielu klas na raz, co nie w ka»dym
j¦zyku jest dost¦pne. Przez dziedziczenie mo»emy np. tworzy¢ nowe typy
wyj¡tków (wtedy dziedziczymy z klasy Exception)
M. Alichniewicz (SKALP)
Python vol. 2
2014
19 / 40
Denicja klasy - denicja metod
Niemal»e obowi¡zkowym elementem klasy s¡ jej metody, czyli funkcje
zawarte wewn¡trz klasy. Metody deniuje si¦ w specyczny sposób:
class Klasa():
def metoda(self, argument1, etc):
""" Docstring metody """
# tutaj tresc metody - teraz pass
pass
To, na co musimy zwróci¢ uwag¦, to pierwszy argument funkcji. Ten
pierwszy argument to nic innego instancja klasy na jakiej dziaªamy, i ten
argument ustawia za nas Python - to oznacza, »e wywoªuj¡c metod¦ go
r¦cznie nie podajemy! Odniesienie do metody odbywa si¦ za pomoc¡
kropki:
instancja = Klasa()
# Pomijamy self!
instancja.metoda('argument1', 'etc')
M. Alichniewicz (SKALP)
Python vol. 2
2014
20 / 40
Denicja klasy - denicja pól klasy
Typowym elementem klas s¡ równie» pola klasy, które mo»emy te»
nazwa¢ atrybutami klasy. W wi¦kszo±ci j¦zyków programowania, np. w
Javie, deniujemy te pola wewn¡trz denicji klasy (czyli denicje s¡ na tym
samym poziomie co metody). Przykªad we wspomnianej Javie:
public class Klasa
public int a =
public int b =
public int c =
}
{
1;
2;
3;
W Pythonie, inicjalizacji zmiennych (pól, atrybutów) klasy dokonujemy
wewn¡trz konstruktora klasy (metoda inicjalizacji klasy), nie na poziomie
denicji klasy! Jak to wi¦c wygl¡da, czyli jak deniujemy konstruktor?
M. Alichniewicz (SKALP)
Python vol. 2
2014
21 / 40
Denicja klasy - denicja pól klasy (konstruktor)
Klasa odpowiadaj¡ca tej w Javie wygl¡da tak:
class Klasa():
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
Konstruktor jest niczym innym jak metod¡ o nazwie __init__, i jest tym
samym co plik __init__.py dla paczek. Warto zwóci¢ uwag¦ jak tworzone
s¡ te zmienne. Jak ju» to zostaªo wspomniane, self to nic innego jak
instancja klasy. A wi¦c tworzymy pola klasy po prostu odwoªuj¡c si¦ do
konkretnej instancji i tworzymy w niej pola jakie chcemy. Z tego te»
wynika, »e mo»emy tworzy¢ nowe pola w locie , czyli w trakcie
dziaªania aplikacji - nie musz¡ by¢ w konstruktorze.
M. Alichniewicz (SKALP)
Python vol. 2
2014
22 / 40
Denicja klasy - konstruktor
Jak przekaza¢ parametry do klasy z zewn¡trz? Tworzymy je jako
argumenty konstruktora, a nast¦pnie podajemy w trakcie tworzenia
instancji:
class Foo():
def __init__(self, *args, **kwargs):
print repr(args)
print repr(kwargs)
bar = Foo(1,2,'trzy', cztery = 4)
M. Alichniewicz (SKALP)
Python vol. 2
2014
23 / 40
Denicja klasy - denicja pól klasy
A co by si¦ staªo, je»eli by wpisa¢ takie pola nie w konstruktorze, a
wewn¡trz klasy na tym samym poziomie co metody? Zanim na to
odpowiemy, trzeba wspomnie¢ o jednej bardzo istotnej i charakterystycznej
dla Pythona rzeczy. Otó» w Pythonie, absolutnie wszystko jest obiektem.
Przez poj¦cie absolutnie wszystko mam na my±li to, »e nie tylko instancje
klas s¡ obiektami. Obiektem jest równie» moduª (caªy), paczka (caªa),
ka»da funkcja, ka»dy typ (wliczaj¡c w to te najprostsze, jak liczba
caªkowita, czy bardziej zªo»one, jak lista). Id¡c tym tropem, obiektem jest
równie» denicja klasy. Czyli, je»eli by±my zdeniowali jakie± pola
wewn¡trz tej klasy, to owszem, byªyby dost¦pne. Jednak jakakolwiek
zmiana ich warto±ci powodowaªaby zmian¦ WE WSZYSTKICH miejscach
gdzie s¡ wykorzystane, niezale»nie od instancji!
M. Alichniewicz (SKALP)
Python vol. 2
2014
24 / 40
Denicja klasy - atrybuty publiczne, prywatne i chronione
Wi¦kszo±¢ obiektowych j¦zyków programowania pozwala na ograniczenie
pól i metod widocznych na zewn¡trz - czyli co± co znamy jako elementy
public, private i protected. Python troch¦ tu upraszcza spraw¦, i nie
posiada widoczno±ci elementów. Oznacza to tyle, »e do ka»dego z
elementów mo»na doj±¢ z zewn¡trz. Python pozwala jednak na tworzenie
elementów które w pewnym sensie s¡ prywatne - ich nazwa zaczyna si¦ od
podwójnego podkre±lenia, np. self.__prywatna_zmienna = 5. Do tak
zdeniowanej zmiennej nie dobierzemy si¦ z zewn¡trz w sposób
instancja.__prywatna_zmienna. Ale dobra¢ si¦ mo»emy: przez
instancja._NazwaKlasy__prywatna_zmienna.
Zwyczajowo zmienne prywatne / chronione zaczynamy po prostu od
podkre±lenia - to samo si¦ dotyczy metod.
M. Alichniewicz (SKALP)
Python vol. 2
2014
25 / 40
Denicja klasy - odwoªanie do pól rodzica
Wraz z dziedziczeniem, pojawia si¦ sytuacja gdzie musimy si¦ dobra¢ do
jakiego± atrybutu (pola, tudzie» metody) klasy rodzica (superklasy).
Zasada w dziedziczeniu jest prosta: jak czego± nie nadpiszemy w subklasie
(klasie dziecku), to atrybuty s¡ przepisane z superklasy. Musimy jednak
pami¦ta¢, »e atrybuty nadajemy w konstruktorze klasy, a bardzo cz¦sto
stworzenie klasy podrz¦dnej wi¡»e si¦ wªa±nie z nadpisaniem konstruktora.
Jak nadpiszemy konstruktor, to nie zostan¡ zainicjalizowane pola klasy
pierwotnej - wi¦c musimy r¦cznie ten nadrz¦dny konstruktor wywoªa¢.
M. Alichniewicz (SKALP)
Python vol. 2
2014
26 / 40
Denicja klasy - odwoªanie do pól rodzica
Python daje nam tutaj do dyspozycji 2 metody.
Bezpo±rednie odwoªanie do metody rodzica . Robimy to w ten
sposób:
def nadpisana_metoda(self, *args, **kwargs):
# Zrob cos z nowa metoda i wolaj rodzica
KlasaNadrzedna.nadpisana_metoda(\
self, *args, **kwargs)
Jak widzicie - odwoªujemy si¦ bezpo±rednio do klasy (wa»ne - to nie
jest jej instancja!). A co tam robi self ? Otó» Python samemu
podaje zmienn¡ self, je»eli wykonujemy metod¦ instancji - bo wtedy
Python wie, na jakim konkretnym obiekcie chcemy t¦ metod¦
wywoªa¢. Je»eli wywoªujemy metod¦ przez klas¦, interpreter nie mo»e
tego stwierdzi¢ - wi¦c musimy mu poda¢ t¡ informacj¦ r¦cznie
(wtedy klasa nadrz¦dna b¦dzie operowa¢ na tym samym obiekcie, co i
podrz¦dna - w ko«cu self si¦ nie zmieni.)
M. Alichniewicz (SKALP)
Python vol. 2
2014
27 / 40
Denicja klasy - odwoªanie do pól rodzica
Wykorzystanie wbudowanej funkcji super . Ta metoda jednak
wymaga, aby klasa najwy»sza w hierarchi (czyli ta od której
si¦ zacz¦ªa zabawa) sama dziedziczyªa z klasy Object (z tej klasy
dziedzicz¡ wszystkie klasy z biblioteki wbudowanej)
def nadpisana_metoda(self, *args, **kwargs):
# Zrob cos z nowa metoda i wolaj rodzica
super(MojaKlasa, self).nadpisana_metoda(\
*args, **kwargs)
Jaka ró»nica? Przede wszystkim - nie podajemy self. Mo»na to
okre±li¢ tak, »e metoda super rzutuje obiekt podany w 2 argumencie
klasy podanej w 1 argumencie na klas¦ rodzica. Na tak zrzutowanym
obiekcie mo»emy wywoªa¢ pierwotn¡ metod¦. Nie musimy równie»
zna¢ nazwy klasy rodzica (chocia» to akurat »aden problem ;))
M. Alichniewicz (SKALP)
Python vol. 2
2014
28 / 40
Denicja klasy - dziedziczenie z wielu klas
Wracaj¡c na chwil¦ do dziedziczenia z wielu klas, rozwa»my nast¦puj¡c¡
sytuacj¦:
Tworzymy klas¦ nadrz¦dn¡ - nazwijmy j¡ A która ma metody
metoda_1 i metoda_2
Tworzymy klas¦ podrz¦dn¡ do A - nazwijmy j¡ B, która NADPISUJE
metod¦ metoda_1
Tworzymy klas¦ podrz¦dn¡ do A (kolejn¡) - nazwijmy j¡ C, która
RÓWNIE› NADPISUJE metod¦ metoda_1
Tworzymy klas¦ dziedzicz¡c¡ z B i C - nazwijmy j¡ D, która dla
odmiany nadpisuje metod¦ metoda_2
Tworzymu instancj¦ klasy D i wywoªujemy metod¦ metoda_1.
M. Alichniewicz (SKALP)
Python vol. 2
2014
29 / 40
Denicja klasy - dziedziczenie z wielu klas
Odpowiedni kod jest przedstawiony poni»ej:
class A(object):
def metoda_1(self):
print 'metoda_1'
def metoda_2(self):
print 'metoda_2'
class B(A):
def metoda_1(self):
print 'metoda_1_B'
class C(A):
def metoda_1(self):
print 'metoda_1_C'
# verte
M. Alichniewicz (SKALP)
Python vol. 2
2014
30 / 40
Denicja klasy - dziedziczenie z wielu klas
class D(B, C):
def metoda_2(self):
print 'metoda_2_D'
# Utworzenie obiektu i wywolanie metody
d = D()
d.metoda_1()
Ten kod si¦ wykona, pomimo pozornego koniktu w implementacji
metody metoda_1. W takim razie, co zostanie wy±wietlone na ekranie?
M. Alichniewicz (SKALP)
Python vol. 2
2014
31 / 40
Denicja klasy - dziedziczenie z wielu klas
Problem ten jest znany w literaturze jako multiple inheritance problem,
albo krócej, diamond problem. Nazwa wywodzi si¦ z diagramu jak
dziedzicz¡ klasy jaki mo»na tutaj narysowa¢ (przypomina on znany z kart
kolor karo, z angielskiego wªa±nie diamonds):
M. Alichniewicz (SKALP)
Python vol. 2
2014
32 / 40
Denicja klasy - dziedziczenie z wielu klas
Mamy konikt - jak wi¦c jest to rozwi¡zane w Pythonie?
Otó», Python zwyczajnie w ±wiecie we¹mie sporn¡ metod¦ z klasy która
jest podana jako pierwsza na li±cie z jakich klas dziedziczymy. Wi¦c
wracaj¡c do naszego kodu:
# Utworzenie obiektu i wywolanie metody
d = D()
d.metoda_1()
Uzyskanym wynikiem b¦dzie w takim razie
metoda1B (czyliwywoaniemetodyzklasyB).
M. Alichniewicz (SKALP)
Python vol. 2
2014
33 / 40
Odczyt dost¦pnych elementów obiektu
Python udost¦pnia ciekaw¡ funkcj¦, która zwraca list¦ atrybutów (pól i
metod) jakie posiada dany obiekt. Funkcja nazywa si¦ dir i zwraca list¦
dost¦pnych pól. W tej li±cie równie» widzimy nasze zmienne prywatne,
opisane w sposób jak na poprzednich slajdach. Przykªad dziaªania:
class Klasa():
pass
instancja = Klasa()
print dir(instancja)
# Wyswietli ['__doc__', '__module__']
To samo mo»emy przeprowadzi¢ np. na liczbie caªkowitej, li±cie, denicji
funkcji czy module.
Co wa»ne, nie wszystkie elementy danego obiektu s¡ zwracane przez
funkcj¦ dir - dziaªanie tej funkcji mo»na zmodykowa¢!
M. Alichniewicz (SKALP)
Python vol. 2
2014
34 / 40
Odczyt dost¦pnych elementów obiektu - modykacja listy
Jak to zrobi¢? Python posiada dosy¢ poka¹ny zbiór metod magicznych jedn¡ z nich ju» poznali±my, czyli __init__. Do oszukania funkcji dir
sªu»y funkcja, która si¦ powinna nazywa¢ __dir__ i zwraca¢ list¦ ci¡gów
tekstowych. Dla przykªadu:
class Klasa():
def __dir__(self):
return ['Chcialbys!]
foo = Klasa()
print dir(foo)
M. Alichniewicz (SKALP)
Python vol. 2
2014
35 / 40
Metody magiczne
Oszukiwanie funkcji dir to nie jest jedyna ciekawa rzecz w Pythonie. Za
pomoc¡ szeregu metod magicznych mo»emy zdeniowa¢ jak nasz obiekt
b¦dzie konwertowany na tekst, liczb¦, co zwróci wykonanie na nim
polecenia repr, co si¦ stanie jak u»yjemy na nim jakiegokolwiek operatora,
jak na przykªad dodawanie, negacja, i inne. Jednym sªowem - deniuj¡c
odpowiednie metody magiczne, mo»emy dokªadnie zdeniowa¢ jak
zachowuje si¦ nasz obiekt!. Dla przykªadu, deniuj¡c np.
klas¦ reprezentuj¡c¡ macierz, mo»emy sprawi¢ »e faktycznie tak si¦ b¦dzie
zachowywa¢ - czyli b¦dzie mo»na przeprowadzi¢ np. operacj¦ mno»enia.
A = Matrix() # Jakas tam macierz - kod abstrakcyjny
B = A * 3 # Pomnozmy elementy razy 3
M. Alichniewicz (SKALP)
Python vol. 2
2014
36 / 40
Zadanie
M. Alichniewicz (SKALP)
Python vol. 2
2014
37 / 40
Zadanie
Doko«czy¢ klas¦ Matrix zaª¡czon¡ do materiaªów. W razie wyst¡pienia
bªedu, rzuca¢ wyj¡tkiem MatrixError (trzeba go najpierw zdeniowa¢)
Przykªad rzucania wyj¡tkiem:
raise TypWyjatku('Tresc bledu')
M. Alichniewicz (SKALP)
Python vol. 2
2014
38 / 40
Materiaªy
M. Alichniewicz (SKALP)
Python vol. 2
2014
39 / 40
Materiaªy
Dokumentacja j¦zyka Python
https://docs.python.org/2/
Forum StackOverow
http://stackoverflow.com/
Why is Object-Oriented Programming Useful?
http://inventwithpython.com/blog/2014/12/02/
why-is-object-oriented-programming-useful-with-an-role-pla
A Guide to Python's Magic Methods
http://www.rafekettler.com/magicmethods.html
M. Alichniewicz (SKALP)
Python vol. 2
2014
40 / 40
Spotkania z Pythonem
Cz¦±¢ 2 - organizacja projektu i obiektowo±¢
Michaª Alichniewicz
Studenckie Koªo Automatyków SKALP
Gda«sk 2014
Dzi¦kuj¦ za uwag¦!
Na licencji Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.
M. Alichniewicz (SKALP)
Python vol. 2
2014
41 / 40
Download