Wykład 2 Programowanie zorientowane obiektowo w Pythonie

Podobne dokumenty
Kurs rozszerzony języka Python

Zaawansowany kurs języka Python

Ćwiczenie 5. Python 3: Programowanie obiektowe i dziedziczenie

Pisząc kod w Pythonie na pewno już nie raz coś poszło nie tak i Shell wypisał komunikat o błędzie podobny do poniższego:

Wyjątki. try - except

Język Python (3) Język Python (3) 1/35

Programowanie obiektowe

Zaawansowany kurs języka Python

Programowanie obiektowe

Kurs rozszerzony języka Python

Wykład 8: klasy cz. 4

Podstawy programowania skrót z wykładów:

Spis treści. Dekoratory. 1 Dekoratory 1.1 Zadanie Zadanie Zadanie Zadanie 4

Zaawansowany kurs języka Python

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Podstawy programowania w Pythonie

Myśl w języku Python! : nauka programowania / Allen B. Downey. Gliwice, cop Spis treści

Programowanie i projektowanie obiektowe

Spis treści. Funkcje. 1 Funkcje 1.1 Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie 7

Język Python. Język Python 1/35

Opis: Instrukcja warunkowa Składnia: IF [NOT] warunek [AND [NOT] warunek] [OR [NOT] warunek].

JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA. Marcin Lewandowski [ ]

Środowisko programisty

Podstawy Programowania C++

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Język Python (2) Język Python (2) 1/36

Python. Wprowadzenie. Jolanta Bachan

Delphi Laboratorium 3

Szablony klas, zastosowanie szablonów w programach

Typy danych, cd. Łańcuchy znaków

Python wprowadzenie. Warszawa, 24 marca PROGRAMOWANIE I SZKOLENIA

Dekoratora używa się wstawiając linijkę zaczynającą się przed definicją dekorowanego obiektu (klasy czy funkcji).

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Programowanie obiektowe

Programowanie i projektowanie obiektowe

Wstęp do programowania

Podstawy Programowania ELEMENTY PROGRAMU i TYPY DANYCH

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

Podstawy programowania. Wykład PASCAL. Zmienne wskaźnikowe i dynamiczne. dr Artur Bartoszewski - Podstawy prograowania, sem.

Programowanie Obiektowe Ćwiczenie 4

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Podstawy Programowania Obiektowego

Zaawansowany kurs języka Python

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Programowanie obiektowe

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Algorytmy i struktury danych

Programowanie w języku Python. Grażyna Koba

Podstawy. Jan Koprowski Politechnika Gdańska, FTiMS Informatyka Stosowana


Dawid Gierszewski Adam Hanasko

JAVA W SUPER EXPRESOWEJ PIGUŁCE

PARADYGMATY PROGRAMOWANIA Wykład 4

TEMAT : KLASY DZIEDZICZENIE

Programowanie Obiektowe i C++

Wykład 4: Klasy i Metody

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

rozdział 4: ZMIENNE I INSTRUKCJE

Oracle PL/SQL. Paweł Rajba.

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Przegląd języka Python. Łukasz Anwajler

Typy metod: konstruktory, destruktory, selektory, zapytania, iteratory.

Podstawy programowania w Pythonie

Programowanie i projektowanie obiektowe

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

Swift (pol. jerzyk) nowy język programowania zaprezentowany latem 2014 r. (prace od 2010 r.)

PHP 5 język obiektowy

10. Programowanie obiektowe w PHP5

Środowisko programisty

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Wykład 5: Klasy cz. 3

2. Składnia Pythona. Robert Janczewski. Gdańsk, 2014

Wykład 2 Składnia języka C# (cz. 1)

Programowanie obiektowe

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Programowanie obiektowe

Dziedziczenie. Streszczenie Celem wykładu jest omówienie tematyki dziedziczenia klas. Czas wykładu 45 minut.

Język programowania zbiór reguł określających, które ciągi symboli tworzą program komputerowy oraz jakie obliczenia opisuje ten program.

Programowanie obiektowe

Programowanie i projektowanie obiektowe

Podstawy bioinformatyki 2017/18

Podstawy i języki programowania

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Programowanie w Sieci Internet. Python: Operacje z plikami oraz obsługa wyjątków

Język programowania Scala / Grzegorz Balcerek. Wyd. 2. Poznań, cop Spis treści

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Języki i metody programowania

Technologie cyfrowe semestr letni 2018/2019

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Python wstęp. Michał Bereta

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Zaawansowane programowanie w języku C++ Klasy w C++

Dziedziczenie. Tomasz Borzyszkowski

1 Kursory 1. 2 Wyjątki Wyjątki predefiniowane Wyjątki niezdefiniowane wcześniej Definiowanie własnych wyjątków...

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Kurs języka Python. Wykład 11. Marcin Młotkowski. 4 stycznia Kontrola poprawności podczas biegu programu. 2 Testowanie oprogramowania

Języki i metody programowania Java. Wykład 2 (część 2)

Właściwości i metody obiektu Comment Właściwości

Transkrypt:

Wykład 2 Programowanie zorientowane obiektowo w Pythonie Plan wykładu: 1. Podstawowe informacje 2. Funkcje specjalne 3. Przeciążanie funkcji i operatorów 4. Dokumentowanie klasy 5. Wbudowane atrybuty obiektu i klasy 6. Konstruktor i destruktor 7. Atrybuty obiektu, atrybuty prywatne, statyczne 8. Łańcuchowa reprezentacja obiektu 9. Funkcje określające prawdziwość obiektu 10. Metody porównania obiektów 11. Metody statyczne 12. Dziedziczenie 13. Dziedziczenie wielopokoleniowe 14. Wyjątki 15. Implementacja kolekcji 1

Z ro dła Strona Marcina Młotkowskiego: http://www.ii.uni.wroc.pl/~marcinm/dyd/python/ James O. Knowlton, Python. Projekty do wykorzystania, Helion Chris Fehily, Po prostu Python, Helion www.python.org 2

Podstawowe informacje Każda klasa dziedziczy po object. Poniżej zdefiniowano pustą klasę class Person(object): pass Definicja klasy kończy się w miejscu, gdzie kończymy wcięcie. Każda metoda klasy jako pierwszy parametr przyjmuje obiekt, w którym jest zdefiniowana (self): class Person(object): def wyswietl_napis(self): print 'Napis' Podczas wywołania metody obiektu nie wymieniamy na liście argumentów self. Jest on automatycznie przekazywany przez Pythona do metody. 3

Funkcje specjalne Nazwy metod specjalnych zawsze rozpoczynają się i kończą dwoma znakami podkreślenia (na przykład init (). Python uruchamia te metody automatycznie, gdy interpreter napotka funkcję wbudowaną lub operator odpowiadający danej metodzie specjalnej. Python używa metod specjalnych w następujących przypadkach: tworzenie i usuwanie egzemplarza; tworzenie reprezentacji łańcuchowych egzemplarza; definiowanie wartości prawdziwości egzemplarza; porównywanie egzemplarzy; dostęp do atrybutów egzemplarza; traktowanie egzemplarzy jak sekwencji i słowników; wykonywanie operacji matematycznych na egzemplarzach. Uwaga: Nie można używać metod specjalnych do zmiany zachowania wbudowanych typów. 4

Przeciąz anie funkcji i operatoro w Przeciążanie funkcji polega na tym, że funkcja o takiej samej nazwie zachowuje się różnie w zależności od typów lub klas podanych argumentów. Python wybiera odpowiednie działanie automatycznie na podstawie parametrów funkcji, co znaczy, że na przykład wywołuje metodę specjalną str (x) po wywołaniu str(x), jeśli x jest egzemplarzem klasy dysponującej metodą str (). Przeciążanie operatora polega na przypisaniu więcej niż jednej funkcji do danego operatora (+,, *,**,t; itp.). Wykonywana operacja zależy od typów lub klas podanych operandów. Np. operator+ wykonuje dodawanie, jeśli jego operandami są liczby, albo łączenie, jeśli operandami są łańcuchy. Metoda specjalna na przykład add () umożliwia określenie sposobu wykonania działania x + y wtedy, gdy x i y są egzemplarzami klasy. 5

Dokumentowanie klasy Na początku definicji klasy możemy umieścić wiersz dokumentacyjny class Point """ A location on the 2D plane """ pass Point. doc A location on the 2D plane Jeżeli nie zostanie podany łańcuch dokumentacyjny to wartością atrybutu doc jest None. Łańcuchy dokumentacyjne można dodawać do metod klasy w taki sam sposób jak do funkcji 6

Atrybuty klasy Wbudowane atrybuty klasy i obiektu klasy dict słownik zawierający przestrzeń nazw danej klasy doc name łańcuch dokumentacyjny klasy nazwa klasy module nazwa modułu w którym została zdefiniowana klasa base krotka (może być pusta) zawierająca klasy nadrzędne w kolejności ich występowania na liście klas nadrzędnych Atrybuty obiektu: dict class słownik zawierający przestrzeń nazw obiektu klasa obiektu 7

Konstruktor i destruktor class Person(object): counter = 0 def init (self): # konstruktor print 'Jestem konstruktorem' def del (self): # destruktor print 'Jestem destruktorem' p = Person() # Jestem konstruktorem del p # Jestem destruktorem 8

Usuwanie egzemplarza Liczba odwołań do obiektu zwiększa się, gdy zostaje on przypisany do nowej nazwy lub umieszczony w kontenerze (liście, kratce lub słowniku). Liczba odwołań do obiektu zmniejsza się, gdy jest on usuwany za pomocą del, gdy odwołanie do niego jest zastępowane innym lub gdy wychodzi poza zakres. Jeśli liczba odwołań do obiektu osiąga zero, Python uruchamia odśmiecanie. >>> a = 39 # Tworzy obiekt <39> >>> b = a # Zwiększa liczbę odwołań do <39> >>>c = [b] #Zwiększa liczbę odwołań do <39> >>> >>> del a #Zmniejsza liczbę odwołań do <39> >>>b = -99 #Zmniejsza liczbę odwołań do <39> >>> c[0] = -1 # Zmniejsza liczbę odwołań do <39> 9

Uwaga dotycząca destruktora Jest on wywoływany wtedy, gdy dany egzemplarz ma być usunięty. Metoda ta może być wykorzystana do oczyszczenia wszelkich zasobów pamięci używanych przez egzemplarz. Metoda del () jest rzadko stosowana w praktyce, ponieważ nie ma gwarancji, że będzie wywołana w określonym odstępie czasu (może się zdarzyć, że nie zostanie wywołana nigdy). Nie warto więc polegać na destruktorze przy operacjach zwalniania zasobów (na przykład przy zamykaniu pliku). Lepsze wyniki można uzyskać definiując jakąś jawnie wywoływaną metodę close(), która wykona także operacje oczyszczające. Instrukcja del nie wywołuje metody _del_() bezpośrednio, lecz zmniejsza o jeden liczbę odwołań do obiektu. Destruktor wywoływany jest tylko wtedy, gdy ta liczba stanie się równa zeru. Zliczanie odwołań nie udaje się dla cyklicznych struktur danych, czyli obiektów odwołujących się nawzajem do siebie. Jeśli na przykład x i y odwołują się do siebie nawzajem, to liczba odwołań nigdy nie stanie się równa zeru, więc nigdy nie nastąpi odśmiecanie (dotyczy to także każdego obiektu, do którego odwołują się obiekty x lub y). Python uruchamia okresowo procedurę wykrywania i usuwania cykli. Proces odśmiecania Pythona nie będzie usuwał cyklicznych egzemplarzy, dla których zdefiniowano metodę del (). Jest to następny powód przemawiający za tym, by nie definiować del ( ). 10

Atrybuty obiektu (instancji) Zmienne instancji definiujemy w konstruktorze: class Person(object): def init (self): self.firstname = 'Jan' self.lastname = 'Kowalski' Możemy również definiować atrybuty po utworzeniu obiektu: Adam = Person(); Adam.wiek = 25; # Tworzymy nowy atrybut i przypisujemy wartość 25 11

Atrybuty prywatne Nazwy elementów prywatnych zaczynamy od class Person(object): private_field = 'top secret' Python zgłasza wyjątek AttributeError przy próbie dostępu z zewnątrz klasy do nazwy prywatnej. 12

Przekręcona nazwa atrybutu prywatnego Python ukrywa nazwę prywatną zmieniając jej nazwę wewnętrzną na _classname attrname. Taki mechanizm zabezpieczania nazywany przekręcaniem nazw jest w istocie iluzją, bowiem można uzyskać dostęp do prywatnego atrybutu posługując się jego przekręconą nazwą. >>> class Point: origin = (0, 0) def change_origin (self, x, y): self. origin = (x,y) print "New origin:", self. origin >>> pt = Point() >>> pt.change_origin(-1,1) New origin : (-1, 1) >>> pt. origin Traceback (most recent call last): File "<stdin> ", line 1, in? AttributeError: Point instance has no attribute origin >>> pt._point origin (-1, 1) 13

Tworzą łańcuchową reprezentację obiektu. class Point: def init (self, x=0, y=0): self.x = x self.y = y def str _ (self): return "(%g,%g)" % (self.x. self.y) def _repr_(self): return "Point(%s.%s)" % (self.x. self.y) Funkcje str () i repr () >>> from point import Point >>> pt = Point(3,9) >>> str(pt) '(3,9)' >>> print pt (3,9) >>> repr(pt) Point(3,9) >>> 'pt' 'Point(3.9)' Nieformalna reprezentacja łańcuchowa egzemplarza jest zwracana przez str() i print(); jego formalna reprezentacja jest zwracana przez repr() i. Formalna reprezentacja łańcuchowa może być użyta do tworzenia kopii egzemplarza. 14

Okres lanie prawdziwos ci obiektu Domyślnie przyjęto, że prawdziwość egzemplarza jest prawdą, lecz za pomocą metody specjalnej nonzero () można nadać jej wartość i zwracać 0 (fałsz) albo 1 (prawda). class Point: def init (self, x=0, y=0): self.x = x self.y = y def str (self): return "(%g, %g)" % (self.x, self.y) def nonzero (self): if self.x ==0 and self.y ==0: return 0 else: return 1 >>> from point import Point >>> pt1 = Point(0,1) >>> pt2 = Point(0,0) >>> pt3 = Point(1,5) >>>for pt in [pt1, pt2, pt3]: if pt: print pt, "is true" else: print pt, "is false" (0. 1) is true (0, 0) is false (1, 5) is true >>> print pt1 and pt2 (0,0) >>> print pt2 or pt3 (0, 5) >>> not pt2 1 15

Metody poro wnania obiekto w Do porównywania egzemplarzy za pomocą wbudowanych operatorów porównania(<,<=,>, >=i!=) można zastosować metody specjalne, które zostały wymienione poniżej. Metody te są nazywane metodami pełnego porównywania. Metoda Wynik lt (self.other) le (self,other) gt (self.other) ge (self,other) eq (self,other) ne (self.other) self < other self <= other self > other self >= other self == other self!= other 16

def comp (self, other): block Jak definiowac metody poro wnania Wielkość comp () jest jedną z metod porównania, które są przedstawione na poprzedniej stronie. Python wywołuje te metody wtedy, gdy egzemplarz zostanie użyty w wyrażeniu porównującym. Wielkość self dotyczy egzemplarza, dla którego wywoływana jest metoda comp (), zaś other jest egzemplarzem, z którym dany egzemplarz jest porównywany. Metoda porównania może zwracać dowolną wartość, lecz jeśli operator porównania zostanie użyty w kontekście logicznym, wartość ta powinna być interpretowanajako wartość logiczna (1 jako prawda, O jako fałsz); w przeciwnym wypadku Python wywołuje wyjątek TypeError. 17

from math import hypot class Point: def init (self, x=0, y=0): self.x = x self.y = y Przykład zastosowania metod poro wnania def _lt_(self, other): return hypot(self.x. self.y)< hypot(other.x, other.y) def _le_(self, other): return hypot(self.x. self.y) <=hypot(other. X, other.y) def _gt_(self, other): return hypot(self.x, self.y) >hypot(other.x, other.y) def _ge_(self, other): return hypot(self.x. self.y) >=hypot(other.x, other.y) 18

def _eq_(self, other): return hypot (self.x, self.y)==hypot(other.x. other y) def _ne_(self. other): return hypot(self.x, self.y)!= hypot(other.x, other.y) >>> from point import Point >>> pt1 = Point(0,0) #Odległość = 0 >>> pt2 = Point(2,2) #Odległość = 2.83 >>> pt3 = Point(3.4) # Odległość = 5 >>> pt4 = Point(-3,4) #Odległość = 5 >>> ptl > pt2 0 >>> pt2 <= pt3 == pt4 1 19

Pozycyjne poro wnanie dwo ch list class Mylist: def init (self, lst): self.lst = lst def _eq_(self, other): result = [] for i in range(len(self.lst)): If self.lst[i] == other.lst[i]: result.append(1) else: result.append(0) return result >>> from mylist import Mylist >>> lst1 = Mylist([1, 2, 3, 4, 5]) >>> lst2 = Mylist([1, 9, 3, 4, 9]) >>> lst1 == lst2 [1, 0, 1, 1, 0] 20

Atrybuty statyczne Definiujemy zaraz po linijce rozpoczynającej definicję klasy: class Person(object): counter = 0 def init (self): Person.counter += 1 def del (self): Person.counter -= 1 p1 = Person() p2 = Person() p1.counter # 2 del p1 p2.counter # 1 21

Metody statyczne Metody statyczne definiujemy poprzedzając je nazwą @staticmethod oraz nie podając parametru self class Person(object): @staticmethod def wypisz_napis(): print 'Napis' Person.wypisz_napis() # Napis 22

Metody prywatne Nazwy metod prywatnych rozpoczynamy od dwóch podkreślników class Person(object): def top_secret_method(): print 'Secret information' p = Person() p. top_secret_method() #' top_secret_method' # Attribute Error: 'Person' object has no attribute 23

Dziedziczenie class Shape: origin = (0.0) shape_name = None def init (self, x=0, y=0): self x = x self y = y def str (self): return "%s, x=%g, y=%g" % (self.shape_name, self.x, self.y) def move(self, delta_x, delta_y): self.x +=delta_x self.y += delta_y class Circle(Shape): shape_name = "circle" def init (self, x=0, y=o, radius=1): Shape init (self. x. y) self.radius = radius def str (self): return Shape. str (self) + (",radius=%g" % (self.radius)) def area(self): return self.radius * self.radius *3.14159 24

class Square(Shape): shape_name = "square" def init (self, x=0, y=0, side=1): Shape init (self, x, y) self.side = side def str_ (self): return Shape. str (self) + (",side=%g" % (self.side)) def area(self): return self.side* self.side >>> from shape import Shape. Circle, Square >>> circle = Circle(0,0,2) >>> square = Square(0,0,3) >>> print circle Circle, x=0, y=0, radius=2 >>> print square Square, x=0, y=0, side=3 >>> print circle.origin, square.origin (0, 0) (0, 0) >>> circle.area() 12.56636 >>> square.area() 9 >>> circle.move( -1,- 2) >>> print circle Circle, x=-1, y=-2, radius=2 >>> square. move(2,3) >>> print square Square, x=2,y=3, side=3 25

Wielodziedziczenie class Samochod: def naprzod(self): class Okret: def naprzod(self): class Amfibia(Lodz,Samochod): problem: amf = Amfibia() amf.naprzod() # która funkcja zostanie wywołana z klasy Samochod czy Okret? 26

Rozwiązywanie konfliktu przy dziedziczeniu wielokrotnym Przeszukiwanie w głąb od lewej do prawej 27

Dostęp do przodka Dostęp do przodka uzyskujemy poprzez metodę super() class ABC(object): def A(self): print 'A from ABC' class A(ABC): def A(self): super(a, self).a() a = A() a.a() # 'A from ABC' 28

Uwagi do dziedziczenia Jeśli klasa podrzędna definiuje atrybut o takiej samej nazwie, jaką ma atrybut jej klasy nadrzędnej, to egzemplarze klasy podrzędnej korzystają z jej atrybutów, chyba że atrybut jest jawnie kwalifikowany za pomocą nazwy klasy nadrzędnej (z operatorem kropki). Wewnątrz egzemplarza klasy podrzędnej Python szuka nazw atrybutów w następującej kolejności: przestrzeń nazw egzemplarza jest ona dostępna poprzez argument self i zawiera zmienne egzemplarza, zmienne prywatne egzemplarza oraz zmienne egzemplarza klasy nadrzędnej; przestrzeń nazw klasy zawiera ona metody, zmienne klasy, metody prywatne i prywatne zmienne klasy; przestrzeń nazw klasy nadrzędnej zawiera ona metody klasy nadrzędnej, zmienne klasy nadrzędnej, metody prywatne klasy nadrzędnej i prywatne zmienne klasy nadrzędnej. Jeśli klasa znajduje się w innym module niż jej klasa nadrzędna, to można kwalifikować nazwę tej klasy nadrzędnej za pomocą nazwy modułu: class subclass(module.superclass) 29

Property class Klasa(object): def init (self): self. x = None def getx(self): return self. x klasa = Klasa() klasa.x = 12 print klasa.x del klasa.x # klasa.setx(12) # print klasa.getx() # klasa.delx() def setx(self, value): self._x = value def delx(self): del self. x x = property(getx, setx, delx, 'Zmienna x'); 30

Property dla atrybutu tylko do odczytu Definicja property voltage dla atrybutu tylko do odczytu _voltage class Parrot(object): def init (self): self._voltage = 100000 @property def voltage(self): """Get the current voltage.""" return self._voltage 31

Property inny sposo b definicji class C(object): def init (self): self._x = None @property def x(self): """I'm the 'x' property.""" return self._x @x.setter def x(self, value): self._x = value @x.deleter def x(self): del self._x 32

Wyjątki Nawet jeżeli wyrażenie Pythona jest składniowo poprawne, może to spowodować błąd podczas próby wykonania. Błędy wykryte podczas wykonywania nazywane są wyjątkami i nie są bezwarunkowo krytyczne. Na kolejnych slajdach zaprezentuję jak obsługiwać wyjątki w programach Pythona. Większość wyjątków nie jest obsługiwanych przez programy i zwracają komunikaty o błędach: >>> 10 * (1/0) Traceback (most recent call last): File "<stdin>", line 1, in? ZeroDivisionError: integer division or modulo by zero >>> 4 + spam*3 Traceback (most recent call last): File "<stdin>", line 1, in? NameError: name 'spam' is not defined >>> '2' + 2 Traceback (most recent call last): File "<stdin>", line 1, in? TypeError: cannot concatenate 'str' and 'int' objects Wyjątki mają różne typy, podawane w komunikacie błędu: ZeroDivisionError, NameError, TypeError. Innymi słowy jest to nazwa wyjątku wbudowanego (identyfikator). 33

Built-in Exceptions lista wbudowanych wyjątków i ich znaczenie. Wyłapywanie wyjątko w try except try statement 1 statement 2 except (id1, id2, id3, ): action 1 action 2 Instrukcja try działa w następujący sposób. Po pierwsze, wykonywane są wyrażenia pomiędzy try a except. Jeśli nie wystąpią wyjątki, klauzula except jest pomijana i wykonanie instrukcji try jest zakończone. Jeśli wystąpi wyjątek podczas wykonywania klauzuli try, reszta statement jest pomijana. Następnie, jeśli jego typ pasuje do wyjątku po słowie kluczowym except, to akcje są wykonywane, a następnie wykonanie przemieszczane jest poza try. Jeśli pojawi się wyjątek, który nie pasuje do wyjątków wymienionych po except, to wyjątek jest przekazywany do zewnętrznych try, jeśli nie znaleziono obsługi wyjątku, to jest to nieobsługiwany wyjątek i wykonanie programu jest zatrzymuje się z komunikatem unhandled exception. 34

try except przykład Wyjątek wywołujemy używając except try: open('/etc/shadow') except IOError, (errno, strerror): print u'wystąpił błąd numer ' + str(errno) + ': ' + strerror Wystąpił błąd Wystąpił błąd numer 13: Permission denied 35

try except nowy przykład >>> while True:... try:... x = int(raw_input("please enter a number: "))... break... except ValueError:... print "Oops! That was no valid number. Try again..." 36

try except else Gdy nie wystąpi wyjątek else try: open('/etc/shadow') except IOError, (errno, strerror): print u'wystąpił błąd numer ' + str(errno) + ': ' + strerror else: print u'plik /etc/shadow otwarty pomyślnie' Wystąpił błąd Wystąpił błąd numer 13: Permission denied Nie było błędu Plik /etc/shadow otwarty pomyślnie 37

try except else finally try: open('/etc/shadow') except IOError, (errno, strerror): print u'wystąpił błąd numer ' + str(errno) + ': ' + strerror else: print u'plik /etc/shadow otwarty pomyślnie' finally: print u'ja wykonam się zawsze' Wystąpił błąd Wystąpił błąd numer 13: Permission denied Ja wykonam się zawsze Nie było błędu Plik /etc/shadow otwarty pomyślnie Ja wykonam się zawsze 38

39

Kilka wyjątko w jednoczes nie try: open('/etc/shadow') print dict['klucz'] except IOError: print u'błąd otwarcia pliku' except KeyError: print u'błąd dostępu do słownika' else: print u'nie wystąpiły błędy' try: open('/etc/shadow') print dict['klucz'] except (IOError, KeyError): print u'wystąpił błąd' else: print u'nie wystąpiły błędy' 40

Kolejny przykład Łapane są również wyjątki nie występujące bezpośrednio w sekcji try ale również te które powstaną w funkcjach wywołanych w sekcji try: >>> def this_fails():... x = 1/0... >>> try:... this_fails()... except ZeroDivisionError as detail:... print 'Handling run-time error:', detail... W przykładzie wykorzystano argument wyjątku detail aby wypisać dodatkowe informacje 41

Tworzenie własnego wyjątku Trzeba zdefiniować klasę pochodną od Exception class MojWyjatek(Exception): pass 42

Tworzenie własnego wyjątku przykład >>> class MyError(Exception): W tym przykładzie przeciążono konstruktor z... def init (self, value): klasy Exception. Nowy konstruktor tworzy... self.value = value... def str (self): atrybut value eliminując standardowe zachowanie polegające na tworzeniu atrybutu args.... return repr(self.value)... >>> try:... raise MyError(2*2)... except MyError as e:... print 'My exception occurred, value:', e.value... My exception occurred, value: 4 >>> raise MyError('oops!') Traceback (most recent call last): File "<stdin>", line 1, in? main.myerror: 'oops!' 43

Obsługa wyjątko w w nowym module class Error(Exception): """Base class for exceptions in this module.""" pass class InputError(Error): """Exception raised for errors in the input. Klasy wyjątków mogą wykonywać dowolne akcje, które mogą wykonywać inne klasy. Zwykle jednak klasy te posiadają proste metody oferując informacje o błędzie. Attributes: expr -- input expression in which the error occurred msg -- explanation of the error """ def init (self, expr, msg): self.expr = expr self.msg = msg class TransitionError(Error): """Raised when an operation attempts a state transition that's not Kiedy tworzymy moduł, w którym może powstać kilka różnych błędów zwykle tworzy się klasę podstawową dla wszystkich wyjątków zdefiniowanych w tym module i klasy pochodne dla każdego nowego typu błędu, który może pojawić się w kodzie modułu. 44

allowed. Attributes: prev -- state at beginning of transition next -- attempted new state msg -- explanation of why the specific transition is not allowed """ def init (self, prev, next, msg): self.prev = prev self.next = next self.msg = msg 45

Introspekcje Informacje o obiekcie dir(obiekt) Dokumentacja obiektu, metody, funkcji help(obiekt) Sprawdzenie czy posiada atrybut hasattr(obiekt, 'nazwa_atrybutu') Pobranie atrybutu getattr(obiekt, 'nazwa_atrybutu') Sprawdzenie czy obiekt jest typu isinstance(obiekt, typ) 46

Introspekcje Sprawdzenie czy obiekt dziedziczy po issubclass(obiekt, podtyp) Sprawdzenie czy obiekt jest wykonywalny callable(obiekt) Lista słów kluczowych keywords Lista obiektów wbudowanych dir( builtins ) Dostęp do docstringów obiekt. doc 47

Introspekcje Nazwa obiektu obiekt. name Pobieranie typu obiektu type(obiekt) Sprawdzanie identyczności obiektów obiekt1 is obiekt2 Dostęp do atrybutów obiektu obiekt. dict Lista przodków klasy: klasa. bases 48

Introspekcje funkcji def fun(a, b=1, c=2, d=3): pass Nazwa funkcji fun.func_name # fun Dokumentacja funkcji fun.func_doc # '' Domyślne wartości funkcji fun.func_defaults # (1,2,3) Obiekt kodu funkcji fun.func_code # <code object fun at 0x98e8f08, file "<ipython console>", line 1> 49

Liczba przyjmowanych argumentów fun.func_code.co_argcount # 4 Liczba zmiennych łącznie z argumentami fun.func_code.co_nlocals # 4 Nazwa pliku w którym znajduje się funkcja Introspekcje funkcji fun.func_code.co_filename # '<ipython console>' Nazwy argumentów i zmiennych lokalnych fun.func_code.co_varnames # ('a', 'b', 'c', 'd') Dane o funkcji 50

fun.func_code.co_flags 0x04 czy użyto *args 0x08 czy użyto **kwargs 51

Sposób korzystania z kolekcji: for element in kolekcja: print x Implementacja kolekcji Szczegóły wykonania: Na początku wywoływana jest metoda iter. Wartością powinien być obiekt (enumerator) implementujący metodę next() która za każdym wywołaniem zwraca kolejny element kolekcji. Metoda next() jest wywoływana tak długo, póki nie zostanie zgłoszony wyjątek StopIteration 52

Implementacja kolekcji zwracającej kolejne liczby od 1 do 10 class ListaLiczb: def iter (self): self.licznik = 0 return self def next(self): if self.licznik >= 10: raise StopIteration self.licznik += 1 return self.licznik 53

Implementacja klasy wektorów Vector: operatory arytmetyczne v1 = Vector([1, 0, 0]) v1 = Vector([0, 1, 0]) v3 = v1 + v2 str(vector([0, 0 1])): <0, 0, 1> len(vector([0, 0 1])): 3 Kolejny przykład (Zadanie) 54

Implementacja wektora class Vector: def init (self, lista): self.value = lista def add (self, arg): if self. class <> arg. class or len(self.value) <> len(arg.value): return None res = Vector( [x + y for x, y in zip(self.value, arg.value) ]) return res Wykorzystanie: v1 = Vector([1, 0, 3]) v2 = Vector([0, 2, 0]) print v1 + v2 55

Konwersja na tekst >>> print Vector([1,2,3]) < main.vector instance at 0xb7eabdec> def str (self): return < +,.join([str(x) for x in self.value]) + > >>> print Vector([1,2,3]) <1, 2, 3> 56

Włas ciwos ci kolekcji Pożądane cechy kolekcji Indeksowany dostęp do danych k[4] Obsługa poprzez iteratory for in rozmiar kolekcji len Dostęp indeksowany: def getitem (self, index): return self.value[index] def setitem (self, index, value): self.value[index] = value Zastosowanie: >>> print v1[k] >>> v1[k] = k 57

def delitem (self, index): del self.value[index] Usuwanie elemento w za pomocą del Długość kolekcji def len (self): return len(self.value) Implementacja kolekcji strona 55. (Przypomnienie) 58

def iter (self): self.indeks = 0 return self Implementacja kolekcji Vector bez generatora def next(self): if self.indeks >= len(self): raise StopIteration self.indeks += 1 return self.value[self.indeks - 1] 59

Włas ciwos ci generatora mechanizm leniwej ewaluacji; przypomina działaniem return, ale zwraca iterator, nie wskazywaną wartość; pozwala zwrócić wartość zachowując stan obliczeń w metodzie/funkcji. Zwrócenie iteratora: instrukcja yield def iter (self): return self.nastepniki() def nastepniki(self): i = 0 while i < len(self): yield self[i] i = i + 1 60

Reimplementacja metody add Poprzednia wersja def add (self, arg): if self. class <> arg. class or len(self.value) <> len(arg.value): return None res = Vector( [x + y for x, y in zip(self.value, arg.value) ]) return res Nowa wersja def add (self, arg): if self. class <> arg. class or len(self) <> len(arg): return None return Vector( [x + y for x, y in zip(self, arg) ]) 61

Definicja klasy Vector Podsumowanie Można używać operatora + ( add ); indeksowany dostęp do współrzędnych ( getitem, setitem ) iteracje po współrzędnych; len() i str(); ukrycie implementacji. 62

Inny przykład yeld Implementacja nieskończonej listy potęg: def power2(): power = 1 while True: yield power power = power * 2 it = power2() for x in range(4): print it.next() Nieskończona pętla for i in power2(): print i 63

Dynamiczne wykonanie programu exec "print 2 + 2" exec open("foo.py") print eval(2*2) 64

Dynamiczna kompilacja kodu Wbudowana funkcja compile(źródło, typ źródła, typ kodu) zwraca obiekt reprezentujący skompilowany kod. x = 10 code = compile(print x\nprint 2*x, <string>, exec) exec code 65

Problem z kontekstem wywołania x = 10 code = compile(print x\nprint 2*x, <string>, exec) wykonaj(code) def wykonaj(kod): exec kod 66

Przekazanie kontekstu wywołania x = 10 code = compile(print x\nprint 2*x, <string>, exec) wykonaj(code) def wykonaj(code): loc = { x : 5} exec code in loc 67