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