• Nie Znaleziono Wyników

Programowanie obiektowe Wyjątki, metody specjalne, generatory Paweł Daniluk

N/A
N/A
Protected

Academic year: 2021

Share "Programowanie obiektowe Wyjątki, metody specjalne, generatory Paweł Daniluk"

Copied!
23
0
0

Pełen tekst

(1)

Programowanie obiektowe

Wyjątki, metody specjalne, generatory

Paweł Daniluk

Wydział Fizyki

Jesień 2016

(2)

Wyjątki

“It’s easier to ask forgiveness than it is to get permission.”

Co zrobić, jeżeli podczas wykonania programu zajdzie nietypowa sytuacja, która wykracza poza założony scenariusz?

Dwie możliwości

1 Sprawdzać przed każdym krokiem, czy można go wykonać.

2 Poczekać, aż wystąpi problem i wtedy go obsłużyć.

Drugi wariant pozwala na rozdzielenie miejsca, gdzie problem występuje, od miejsca gdzie jest obsługiwany.

(3)

Idea

Rzucanie

W momencie wystąpienia sytuacji nietypowej jest tworzony i rzucany wyjątek.

Przechwytywanie

W miejscu, gdzie jest możliwe obsłużenie błędu wyjątek jest przechwytywany.

(4)

Bez wyjątków

d e f c z y t a j 1 ( f ) : l i n e =f . r e a d l i n e ( )

i f l i n e== ’ ’ : # k o n i e c p l i k u r e t u r n ( None , ’EOF ’ ) e l s e :

r e t u r n (A( l i n e ) , ’OK ’ )

d e f c z y t a j 2 ( f ) : . . .

d e f c z y t a j ( f ) : done=F a l s e w h i l e not done :

( r e s A , s t a t u s )= c z y t a j 1 ( f ) i f s t a t u s== ’EOF ’ :

r e t u r n ( None , ’EOF ’ ) ( r e s B , s t a t u s )= c z y t a j 2 ( f ) i f s t a t u s== ’EOF ’ :

r e t u r n ( None , ’EOF ’ ) r e s . e x t e n d ( ( r e s A , r e s B ) ) done=p r z e t w o r z ( r e s A , r e s B ) r e t u r n ( r e s , ’OK ’ )

(5)

Bez wyjątków c.d.

d e f main ( ) : f = . . .

( r e s , s t a t u s )= c z y t a j ( f ) i f s t a t u s== ’EOF ’ :

p r i n t " B l a d "

e l s e :

p r i n t ’OK ’

(6)

Z wyjątkami

c l a s s E O F E x c e p t i o n ( E x c e p t i o n ) : p a s s

d e f c z y t a j 1 ( f ) : l i n e =f . r e a d l i n e ( )

i f l i n e== ’ ’ : # k o n i e c p l i k u r a i s e E O F E x c e p t i o n ( ) r e t u r n A( l i n e )

d e f c z y t a j 2 ( f ) : . . .

d e f c z y t a j ( f ) : done=F a l s e w h i l e not done :

r e s A=c z y t a j 1 ( f ) r e s B=c z y t a j 2 ( f )

r e s . e x t e n d ( ( r e s A , r e s B ) ) done=p r z e t w o r z ( r e s A , r e s B ) r e t u r n ( r e s )

(7)

Z wyjątkami c.d.

d e f main ( ) : f = . . . t r y :

r e s=c z y t a j ( f ) p r i n t ’OK ’ e x c e p t E O F E x c e p t i o n :

p r i n t " B l a d "

(8)

Co się może zdarzyć

błędy arytmetyczne (dzielenie przez 0, pierwiastek z liczby ujemnej) pusta lista

brak klucza w słowniku błędne dane na wejściu brak pliku, zła nazwa wyjście poza zakres ...

(9)

Przechwytywanie wyjątków

Instrukcja try

t r y:

f=open ( . . . )

d o S o m e t h i n g ( . . . ) # kod , k t o r y moze w y g e n e r o w a c w y j a t e k e x c e p t E x c e p t i o n 1 a s e :

p r o c e s s _ e x c e p t i o n ( e ) # p r z e c h w y c o n o w y j a t e k k l a s y E x c e p t i o n 1 e x c e p t E x c e p t i o n 2 :

p r i n t " O l a b o g a ! ! ! " # p r z e c h w y c o n o w y j a t e k k l a s y E x c e p t i o n 2 e l s e:

j e s t S u p e r ( ) # n i e w y s t a p i l z a d e n w y j a t e k f i n a l l y :

f . c l o s e ( ) # n i e z a l e z n i e co s i e s t a l o t r z e b a p o s p r z a t a c

Wyjątek jest przechwytywany przez najgłębiej zagnieżdżoną istrukcję try , która ma pasującą klauzulę except .

Catch only what you can handle.

(10)

Przykład

Brak klucza w słowniku i f k i n d :

r e t u r n d [ k ] e l s e:

r e t u r n None

t r y:

r e t u r n d [ k ] except K e y E r r o r :

r e t u r n None

(11)

Wyjątki standardowe

ArithmeticError nadklasa obejmująca wyjątki związane z błędami numerycznymi

AssertionError niespełniona asercja w instrukcji assert AttributeError brak atrybutu

IndexError brak elementu o podanym indeksie KeyError brak klucza w słowniku

NameError brak zmiennej

NotImplementedError nie zaimplementowana funkcjonalność OverflowError przepełnienie

StopIteration koniec iteracji (podnoszony w metodzie next() iteratora) ZeroDivisionError dzielenie przez 0

(12)

Podnoszenie wyjątku

W wielu sytuacjach wyjątek jest podnoszony samoczynnie (np. przez metody biblioteki standardowej).

Instrukcja raise

r a i s e M y E x c e p t i o n ( " Message " , d a t a )

Własne wyjątki

Można definiować własne wyjątki. Muszą one dziedziczyć z klasy Exception .

c l a s s M y E x c e p t i o n ( E x c e p t i o n ) :

d e f __init__ ( s e l f , message , d a t a ) :

s e l f . message , s e l f . d a t a=message , d a t a d e f __str__ ( s e l f ) :

r e t u r n m e s s a g e+ ’ : : ’+s t r ( d a t a )

(13)

Metody specjalne

W Pythonie obiekty mogą mieć metody, które są wywoływane przy użyciu specjalnej składni.

Przykładem jest metoda __init__ , która jest wywoływana automatycznie po stworzeniu obiektu.

(14)

Zamiana na napis

object.__repr__(self) zwraca reprezentację obiektu, która jest zgodna ze składnią Pythona, lub jeśli to niemożliwe napis postaci

‘<opis obiektu>’, który jest użyteczny przy debugowaniu – wywoływana przez repr(object)

object.__str__(self) zwraca “ładny” napis – wywoływana przez str(object)

(15)

Kontenery

object.__len__(self) liczba elementów – wywoływana przez len(object) object.__getitem__(self, key) pobieranie wartości – wywoływana przez

object[key]

object.__setitem__(self, key, value) zmiana – wywoływana przez object[key]=value

object.__delitem__(self, key) usuwanie – wywoływana przez del object[key]

object.__iter__(self) iterator

object.__reversed__(self) iterator iterujący w przeciwnym kierunku – wywoływana przez reversed(object)

object.__contains__(self, item) zawieranie – wywoływana przez item in object

(16)

Operacje arytmetyczne

object.__add__(self, other) object + other object.__sub__(self, other) object - other object.__mul__(self, other) object * other object.__div__(self, other) object / other object.__floordiv__(self, other) object // other object.__mod__(self, other) object % other

object.__divmod__(self, other) divmod(object, other) object.__pow__(self, other) object ** other

object.__lshift__(self, other) object << other object.__rshift__(self, other) object >> other object.__and__(self, other) object & other object.__xor__(self, other) object ˆ other object.__or__(self, other) object | other

(17)

Operacje arytmetyczne c.d.

object.__neg__(self) -object object.__pos__(self) +object object.__abs__(self) abs(object) object.__invert__(self) ˜object

(18)

Porównywanie

object.__lt__(self, other) object < other object.__le__(self, other) object <= other object.__eq__(self, other) object == other object.__ne__(self, other) object != other object.__gt__(self, other) object > other object.__ge__(self, other) object >= other

object.__cmp__(self, other) zwraca wartość ujemną jeżeli object <

other , zero jeżeli object==other i liczbę dodatnią jeżeli object > other

(19)

Generatory

Problem

Jak napisać funkcję (metodę), która oblicza i zwraca wiele (dowolnie wiele) wartości?

Można zwracać listę, ale to nie rozwiązuje problemu nieograniczonej liczby wyników. Dodatkowo jest czasochłonne.

Idealnym rozwiązaniem byłaby funkcja, która może wielokrotnie wykonać instrukcję return .

Przykład (życzeniowy) d e f k w a d r a t y ( s t a r t ) :

n= s t a r t w h i l e True :

r e t u r n n ∗ n n += 1

(20)

Generatory c.d.

Trzeba jakoś pamiętać stan funkcji i ją wznawiać. Można to emulować definiując odpowiednią klasę.

c l a s s Kwadraty :

d e f __init__ ( s e l f , s t a r t ) : s e l f . n = s t a r t

d e f n e x t( s e l f ) :

r e s = s e l f . n ∗ s e l f . n s e l f . n += 1

r e t u r n r e s k = Kwadraty ( 5 ) f o r i i n r a n g e( 3 ) :

p r i n t k . n e x t ( )

(21)

Generatory c.d.

Python ma magiczną instrukcję yield, która znacząco upraszcza sytuację.

d e f k w a d r a t y ( s t a r t ) : n = s t a r t

w h i l e True : y i e l d n ∗ n n += 1

k = k w a d r a t y ( 5 ) # k j e s t i n s t a n c j a g e n e r a t o r a f o r i i n r a n g e( 3 ) :

p r i n t k . n e x t ( )

(22)

Generatory c.d.

Każda funkcja zawierająca instrukcję yield zwraca instancję generatora.

Taka funkcja może mieć wyłącznie bezargumentowe instrukcje return , które kończą pracę generatora wyjątkiem StopIteration .

Generatory doskonale nadają się do implementowania iteratorów, ponieważ mają metody __iter__() i next() .

Generatory mają również metody send(value) , throw(exception) i close() , które służą do przesyłania danych do generatora i podnoszenia w nim wyjątków.

(23)

Coroutines

i m p o r t random

d e f g e t _ d a t a ( ) :

""" R e t u r n 3 random i n t e g e r s b e t w e e n 0 and 9 """

r e t u r n random . s a m p l e ( r a n g e ( 1 0 ) , 3 )

d e f consume ( ) :

""" D i s p l a y s a r u n n i n g a v e r a g e a c r o s s l i s t s o f i n t e g e r s s e n t t o i t """

r u n n i n g _ s u m = 0 d a t a _ i t e m s _ s e e n = 0

w h i l e T r u e : d a t a = y i e l d

d a t a _ i t e m s _ s e e n += l e n ( d a t a ) r u n n i n g _ s u m += sum ( d a t a )

p r i n t( ’ The ␣ r u n n i n g ␣ a v e r a g e ␣ i s ␣ {} ’ . f o r m a t ( r u n n i n g _ s u m / f l o a t( d a t a _ i t e m s _ s e e n ) ) )

d e f p r o d u c e ( c o n s u m e r ) :

""" P r o d u c e s a s e t o f v a l u e s and f o r w a r d s them t o t h e p r e −d e f i n e d c o n s u m e r f u n c t i o n """

w h i l e T r u e :

d a t a = g e t _ d a t a ( )

p r i n t( ’ P r o d u c e d ␣ {} ’ . f o r m a t ( d a t a ) ) c o n s u m e r . s e n d ( d a t a )

y i e l d

i f __name__ == ’__main__ ’ : c o n s u m e r = consume ( ) c o n s u m e r . s e n d ( None )

p r o d u c e r = p r o d u c e ( c o n s u m e r )

f o r _ i n r a n g e( 1 0 ) : p r i n t( ’ P r o d u c i n g . . . ’ ) n e x t( p r o d u c e r )

Cytaty

Powiązane dokumenty

Metody statyczne powodują kłopoty przy dziedziczeniu, jeżeli atrybuty, do których się odnoszą są przysłonięte w podklasie... Metody statyczne

Czasami występuje potrzeba opisu klas, które łączą w sobie cechy kilku klas nadrzędnych (np. latająca łódź). Wielodziedziczenie może powodować straszne problemy (Deadly Diamond

Katalogi w strukturze plików serwisu odpowiadają klasom Elementy katalogów (pliki i podkatalogi) odpowiadają atrybutom Aplikacja jest autonomicznym serwerem webowym. Treść nie

Paradygmat obiektowy doskonale nadaje się do opisywania struktury i stanu dużych systemów.. Niestety takie systemy rzadko kiedy pozostają niezmienne

Funkcje i klasy dające możliwie prosty sposób wyrażania operacji na reprezentacjach przetwarzanych informacji..

Gwiezdne Wojny 1977 124 kolor Potężne Kaczory 1991 104 kolor Świat Wayne’a 1992 95 kolor.. Daniluk(Wydział Fizyki)

javax.sql.rowset.serial Provides utility classes to allow serializable mappings be- tween SQL types and data types in the Java programming language.. javax.sql.rowset.spi The

Za pomocą klas programista stara się opisać obiekty, ich właściwości, zbudować konstrukcje, interfejs, dzięki któremu będzie można wydawać polecenia realizowane potem