Programowanie i projektowanie obiektowe

Podobne dokumenty
Programowanie i projektowanie obiektowe

Programowanie i projektowanie obiektowe

Programowanie i projektowanie obiektowe

Programowanie obiektowe

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

Kurs rozszerzony języka Python

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

Programowanie i projektowanie obiektowe

Programowanie obiektowe

Programowanie i projektowanie obiektowe

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

Diagramy klas. dr Jarosław Skaruz

Oracle PL/SQL. Paweł Rajba.

Programowanie obiektowe

Kurs WWW. Paweł Rajba.

Programowanie i projektowanie obiektowe

Klasy abstrakcyjne, interfejsy i polimorfizm

Programowanie obiektowe

Wstęp do programowania

PHP 5 język obiektowy

Programowanie obiektowe

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

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

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Programowanie obiektowe - 1.

Typy klasowe (klasy) 1. Programowanie obiektowe. 2. Założenia paradygmatu obiektowego:

Programowanie w Javie 1 Wykład i Ćwiczenia 3 Programowanie obiektowe w Javie cd. Płock, 16 października 2013 r.

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

Programowanie i projektowanie obiektowe

Klasy Obiekty Dziedziczenie i zaawansowane cechy Objective-C

Metaprogramowanie w Ruby

Python in the Enterprise

Programowanie Obiektowe i C++

Common Lisp - funkcje i zmienne

Programowanie obiektowe

Wykład 8: klasy cz. 4

Technologie i usługi internetowe cz. 2

Programowanie Obiektowe i C++

Definicje klas i obiektów. Tomasz Borzyszkowski

Programowanie obiektowe

1 Atrybuty i metody klasowe

Operator przypisania. Jest czym innym niż konstruktor kopiujący!


Dziedziczenie. dr Jarosław Skaruz

Podstawy Programowania Obiektowego

Dokumentacja do API Javy.

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Podstawy Języka Java

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

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

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

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

10. Programowanie obiektowe w PHP5

Wstęp do programowania

Zaawansowany kurs języka Python

Programowanie obiektowe w VB cz 2

Programowanie, część I

Ćwiczenie 5. Python 3: Programowanie obiektowe i dziedziczenie

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

Aplikacje w środowisku Java

Materiały do zajęć VII

Język C++ Programowanie obiektowe

Programowanie 2. Język C++. Wykład 3.

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Zaawansowany kurs języka Python

Programowanie Obiektowe i C++

Programowanie Obiektowe i C++ Marcin Benke

Programowanie obiektowe

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

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

Paweł Kurzawa, Delfina Kongo

Projektowanie obiektowe oprogramowania Wykład 4 wzorce projektowe cz.i. wzorce podstawowe i kreacyjne Wiktor Zychla 2017

Programowanie obiektowe w języku

Programowanie Obiektowe i C++

Dziedziczenie. Ogólna postać dziedziczenia klas:

Programowanie Obiektowe i C++

Wykład 5: Klasy cz. 3

Wywoływanie metod zdalnych

Spis treści. The Zen of Python

Inne podejścia obiektowe. Referat na seminarium magisterskie Zagadnienia Programowania Obiektowego Dymitr Pszenicyn

Wstęp. Ale po co? Implementacja

Rysunek 1: Przykłady graficznej prezentacji klas.

> C++ dziedziczenie. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki

Analiza i projektowanie obiektowe 2016/2017. Wykład 11: Zaawansowane wzorce projektowe (1)

Technologie obiektowe

Dziedziczenie w Javie

Podstawy programowania. Wykład PASCAL. Wstęp do programowania obiektowego. dr Artur Bartoszewski - Podstawy programowania, sem.

Polimorfizm. dr Jarosław Skaruz

Przeciążanie operatorów

Laboratorium 7 Blog: dodawanie i edycja wpisów

Programowanie obiektowe. Dr hab. Inż. Marta Gładysiewicz-Kudrawiec Pokój 229 A1 Operatory new delete pliki-odczyt

Marcin Luckner Politechnika Warszawska Wydział Matematyki i Nauk Informacyjnych

java.util.* :Kolekcje Tomasz Borzyszkowski

Dziedziczenie. Tomasz Borzyszkowski

Język Java część 2 (przykładowa aplikacja)

Podstawy programowania w Pythonie

Programowanie obiektowe

Różne właściwości. Różne właściwości. Różne właściwości. C++ - klasy. C++ - klasy C++ - KLASY

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

Transkrypt:

Programowanie i projektowanie obiektowe Python od środka Paweł Daniluk Wydział Fizyki Jesień 2013 P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 1 / 40

Zasięgi nazw (ang. scopes) Przestrzeń nazw Mapowanie nazw (zmiennych) do wartości (obiektów). Jest związane z: klasami obiektami modułami Dodatkowo występują przestrzenie: lokalna (locals()) globalna (globals()) wbudowana ( builtin ) Przestrzenie nazw są niezależne. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 2 / 40

Zasięgi nazw (ang. scopes) Zasięgi Zasięgi są związane z funkcjami. Zmienne występujące w funkcji są widoczne w jej leksykalnym obrębie i należą do lokalnej przestrzeni nazw. Przypisanie zawsze dotyczy najsilniej zagnieżdżonego zasięgu. Zasięg, w którym funkcja została zdefiniowana istnieje wraz z nią. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 3 / 40

Zasięgi przykłady d ef f ( ) : p r i n t ( x ) x = g l o b a l f ( ) d ef f ( ) : x = f p r i n t ( x ) x = g l o b a l p r i n t ( x ) f ( ) p r i n t ( x ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 4 / 40

Zasięgi przykłady d ef f ( ) : p r i n t ( x ) x = f x = g l o b a l f ( ) d ef f ( ) : p r i n t ( x ) d ef g ( ) : g l o b a l x p r i n t ( x ) x = g x = g l o b a l f ( ) g ( ) f ( ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 5 / 40

Zasięgi przykłady x = g l o b a l d ef f ( ) : d e f g ( ) : g l o b a l x p r i n t ( x ) x = f g ( ) f ( ) d ef f ( ) : d e f g ( ) : n o n l o c a l x = g x = f g ( ) p r i n t ( x ) x x = g l o b a l f ( ) p r i n t ( x ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 6 / 40

Implementacja przestrzeni nazw Przestrzenie nazw są zazwyczaj implementowane przy pomocy słowników. Często słownik dostępny jest przez atrybut dict. Funkcje locals() globals() dir([object]) zwraca zmienne w bieżącym zasięgu lub atrybuty dostępne w obiekcie (niekoniecznie własne) Można zrobić klasę, której obiekty nie mają atrybutu dict. Służy do tego atrybut slots. c l a s s A( o b j e c t ) : slots =[ a1, a2 ] Klasa A ma tylko dwa atrybuty a1 i a2. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 7 / 40

Typy i obiekty Każda wartość w Pythonie jest obiektem (nawet liczba). Każdy obiekt ma unikalny identyfikator (id()) Każdy obiekt ma typ (type()) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 8 / 40

Typy wbudowane w Pythona None NotImplemented Ellipsis numbers.number numbers.integral numbers.real numbers.complex Sequences immutable strings unicode tuples mutable lists byte arrays P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 9 / 40

Typy wbudowane w Pythona sets set frozenset mappings callable types user-defined functions user-defined methods generator functions built-in functions built-in methods class types (new-style) classic classes class instances (czasem) modules classes class instances files P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 10 / 40

Funkcje są obiektami Funkcje mogą być traktowane jak wartości: przypisywane na zmienną, przekazywane jako parametry. Funkcje mogą mieć atrybuty. >>> def f():... pass... >>> f.atr=1 >>> f.atr 1 P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 11 / 40

Funkcje są obiektami Funkcje nazwane d ef f ( x ) : r e t u r n x+1 Funkcje anonimowe f=lambda x : x+1 P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 12 / 40

Czym się różni funkcja od metody? >>> class A():... def f(self):... pass... >>> A. dict module : main, doc : None, f : <function f at 0x10e3615f0> >>> A.f <unbound method A.f> >>> A().f <bound method A.f of < main.a instance at 0x10e1fdb90>> Funkcje są atrybutami klas. Pobranie atrybutu, który jest funkcją, skutkuje zwróceniem metody. Metoda może być przywiązana lub nie. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 13 / 40

Czym się różni funkcja od metody? c.d. Metody mają atrybuty: im_class klasa im_func funkcja (atrybut klasy) im_self obiekt (określony tylko w metodzie przywiązanej) Metoda przywiązana Obiekt, który można wywołać (ma metodę call. Wywołanie powoduje przekazanie do funkcji parametru self oraz pozostałych podanych w wywołaniu metody. Metoda nieprzywiązana Metoda nieprzywiązana różni się od funkcji tym, że weryfikuje, czy pierwszy parametr jest instancją klasy, z której metoda pochodzi. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 14 / 40

Nowe i stare klasy (new-style classes, classic classes Classic classes Niezależne od systemu typów. Instancje klas są typu <type instance >. New-style classes Włączone w system typów. Typ instancji jest równy jej klasie. Dziedziczą z klasy object. Możliwości klas w nowym stylu metody statyczne i klasowe cechy i deskryptory lepsze wielodziedziczenie metaklasy slots P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 15 / 40

Wielodziedziczenie (ang. multiple inheritance 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 problemu (Deadly Diamond of Death). Niezwykle istotne są reguły wyszukiwania metod (Method Resolution Order MRO). P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 16 / 40

Wielodziedziczenie (ang. multiple inheritance 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 problemu (Deadly Diamond of Death). Niezwykle istotne są reguły wyszukiwania metod (Method Resolution Order MRO). Stare i nowe klasy różnią się MRO. W nowych klasach zawsze występuje diament (bo dziedziczą z object). Linearyzacja Kolejność klas w MRO zachowuje porządek wynikający z dziedziczenia (nadklasa zawsze po podklasie) i kolejności występowania nadklas w definicji klasy. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 16 / 40

Wielodziedziczenie c.d. Niektóre hierarchie nie pozwalają na linearyzację c l a s s A( o b j e c t ) : d e f meth ( s e l f ) : r e t u r n "A" c l a s s B( o b j e c t ) : d e f meth ( s e l f ) : r e t u r n "B" c l a s s X(A, B ) : pass c l a s s Y(B, A ) : pass c l a s s Z(X, Y ) : pass P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 17 / 40

Jak dostać się do nadklasy? Metoda rozszerzająca zazwyczaj wywołuje metodę z nadklasy. Problem c l a s s A( o b j e c t ) : d e f m( s e l f ) : " s a v e A s data " c l a s s B(A ) : d e f m( s e l f ) : " s a v e B s data " A.m( s e l f ) c l a s s C(A ) : d e f m( s e l f ) : " s a v e C s data " A.m( s e l f ) c l a s s D(B, C ) : d e f m( s e l f ) : " s a v e D s data " B.m( s e l f ) ; C.m( s e l f ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 18 / 40

Jak dostać się do nadklasy? Metoda rozszerzająca zazwyczaj wywołuje metodę z nadklasy. Problem c l a s s A( o b j e c t ) : d e f m( s e l f ) : " s a v e A s data " c l a s s B(A ) : d e f m( s e l f ) : " s a v e B s data " A.m( s e l f ) c l a s s C(A ) : d e f m( s e l f ) : " s a v e C s data " A.m( s e l f ) c l a s s D(B, C ) : d e f m( s e l f ) : " s a v e D s data " B.m( s e l f ) ; C.m( s e l f ) Wywołanie D.m() spowoduje dwukrotne wykonanie A.m(). P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 18 / 40

Jak dostać się do nadklasy? c l a s s A( o b j e c t ) : d e f m( s e l f ) : " s a v e A s data " c l a s s B(A ) : d e f _m( s e l f ) : " s a v e B s data " d e f m( s e l f ) : s e l f._m( ) ; A.m( s e l f ) c l a s s C(A ) : d e f _m( s e l f ) : " s a v e C s data " d e f m( s e l f ) : s e l f._m( ) ; A.m( s e l f ) c l a s s D(B, C ) : d e f _m( s e l f ) : " s a v e D s data " d e f m( s e l f ) : s e l f._m( ) ; B._m( s e l f ) ; C._m( s e l f ) ; A.m( s e l f ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 19 / 40

Jak dostać się do nadklasy? c l a s s A( o b j e c t ) : d e f m( s e l f ) : " s a v e A s data " c l a s s B(A ) : d e f _m( s e l f ) : " s a v e B s data " d e f m( s e l f ) : s e l f._m( ) ; A.m( s e l f ) c l a s s C(A ) : d e f _m( s e l f ) : " s a v e C s data " d e f m( s e l f ) : s e l f._m( ) ; A.m( s e l f ) c l a s s D(B, C ) : d e f _m( s e l f ) : " s a v e D s data " d e f m( s e l f ) : s e l f._m( ) ; B._m( s e l f ) ; C._m( s e l f ) ; A.m( s e l f ) To rozwiązanie jest poprawne, ale implementacja D musi uwzględnić istnienie klasy A. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 19 / 40

Strategia następnej metody c l a s s A( o b j e c t ) : d e f m( s e l f ) : " s a v e A s data " c l a s s B(A ) : d e f m( s e l f ) : " s a v e B s data " ; s u p e r (B, s e l f ).m( ) # C c l a s s C(A ) : d e f m( s e l f ) : " s a v e C s data " ; s u p e r (C, s e l f ).m( ) # A c l a s s D(B, C ) : d e f m( s e l f ) : " s a v e D s data " ; s u p e r (D, s e l f ).m( ) # B A. mro == (A, o b j e c t ) B. mro == (B, A, o b j e c t ) C. mro == (C, A, o b j e c t ) D. mro == (D, B, C, A, o b j e c t ) super(class, obj) nie musi być nadklasą class jest nadklasą obj. class obj musi być instancją pewnej podklasy class P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 20 / 40

Jak powstają metody? >>> class A(object):... def f(self): pass... >>> A. dict [ f ] <function f at 0x10be7f140> >>> A.f <unbound method A.f> >>> A().f <bound method A.f of < main.a object at 0x10bea10d0>> Funkcja ma metodę get (self, obj, objtype=none). >>> def g(self):pass... >>> g. get (None, A) <unbound method A.g> >>> g. get (A(), A) <bound method A.g of < main.a object at 0x10bea1250>> P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 21 / 40

Jak powstają metody? Zamiast funkcji możemy mieć dowolny obiekt, który ma metodę get. c l a s s RandFun ( o b j e c t ) : def init ( s e l f, a r g s ) : s e l f. f l i s t =a r g s def get ( s e l f, obj, o b j t y p e=none ) : r e t u r n random. c h o i c e ( s e l f. f l i s t ). get ( obj, o b j t y p e ) c l a s s A( o b j e c t ) : def f 1 ( s e l f ) : p r i n t " Jestem f 1 " def f 2 ( s e l f ) : p r i n t " Jestem f 2 " def g ( s e l f, v a l ) : p r i n t " Jestem g : "+s t r ( v a l ) r f=randfun ( f1, f 2 ) r f g=randfun ( f1, f2, f g ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 22 / 40

Deskryptory Obiekt implementujący co najmniej jedną z metod get (), set(), delete() nazywa się deskryptorem. c l a s s R e v e a l A c c e s s ( o b j e c t ) : def init ( s e l f, i n i t v a l =None, name= v a r ) : s e l f. v a l = i n i t v a l s e l f. name = name def get ( s e l f, obj, o b j t y p e ) : p r i n t R e t r i e v i n g, s e l f. name r e t u r n s e l f. v a l def set ( s e l f, obj, v a l ) : p r i n t Updating, s e l f. name s e l f. v a l = v a l c l a s s B( o b j e c t ) : x = R e v e a l A c c e s s ( 1 0, v a r " x " ) y = 5 P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 23 / 40

Deskryptory c.d. Deskryptory pozwalają na łatwą realizację kapsułkowania. property(fget=none, fset=none, fdel=none, doc=none) c l a s s C( o b j e c t ) : d e f g e t x ( s e l f ) : r e t u r n s e l f. x d e f s e t x ( s e l f, v a l u e ) : s e l f. x = v a l u e d e f d e l x ( s e l f ) : d e l s e l f. x x = p r o p e r t y ( getx, s e t x, d e l x, " I m the x p r o p e r t y. " ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 24 / 40

Metody statyczne Przy pomocy deskryptorów można zrealizować metody statyczne. c l a s s s t a t i c m e t h o d ( o b j e c t ) : d e f init ( s e l f, f ) : s e l f. f = f d e f get ( s e l f, obj, o b j t y p e=none ) : r e t u r n s e l f. f P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 25 / 40

... i klasowe c l a s s c l a s s m e t h o d ( o b j e c t ) : d e f init ( s e l f, f ) : s e l f. f = f d e f get ( s e l f, obj, k l a s s=none ) : i f k l a s s i s None : k l a s s = t y p e ( o b j ) d e f newfunc ( a r g s ) : r e t u r n s e l f. f ( k l a s s, a r g s ) r e t u r n newfunc P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 26 / 40

@dekoratory Metody statyczne (i klasowe) można tworzyć korzystając z klas staticmethod i classmethod. c l a s s A( o b j e c t ) : d e f f ( ) : pass s t a t i c=s t a t i c m e t h o d ( f ) d e f g ( c l s ) : pass g=c l a s s m e t h o d ( g ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 27 / 40

@dekoratory c.d. Ale zazwyczaj stosuje się zapożyczoną z Javy składnię. c l a s s A( o b j e c t ) : @ s t a t i c m e t h o d def f ( ) : pass @ classmethod def g ( c l s ) : pass P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 28 / 40

@dekoratory c.d. Napis: @ d e k o r a t o r d ef f ( arg ) :... oznacza: d ef f ( arg ) :... f=d e k o r a t o r ( f ) Dekorator funkcji jest funkcją, która jako argument bierze funkcję dekorowaną i zwraca zmodyfikowaną funkcję. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 29 / 40

@dekoratory c.d. Przykład d ef bread ( f u n c ) : d e f wrapper ( ) : p r i n t " </ \ > " f u n c ( ) p r i n t "<\ />" r e t u r n wrapper d ef i n g r e d i e n t s ( f u n c ) : d e f wrapper ( ) : p r i n t "#tomatoes#" f u n c ( ) p r i n t "~ s a l a d ~" r e t u r n wrapper d ef sandwich ( food=" ham " ) : p r i n t food P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 30 / 40

@dekoratory c.d. Przykład sandwich ( ) #o u t p u t s : ham sandwich = bread ( i n g r e d i e n t s ( sandwich ) ) sandwich ( ) #o u t p u t s : #</ \ > # #tomatoes# # ham # ~ s a l a d ~ #<\ /> P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 31 / 40

@dekoratory c.d. @bread @ i n g r e d i e n t s d ef sandwich ( food=" ham " ) : p r i n t food sandwich ( ) #o u t p u t s : #</ \ > # #tomatoes# # ham # ~ s a l a d ~ #<\ /> P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 32 / 40

@dekoratory c.d. Kolejność ma znaczenie @ i n g r e d i e n t s @bread d ef strange_sandwich ( food=" ham " ) : p r i n t food strange_sandwich ( ) #o u t p u t s : ##tom ato es# #</ \ > # ham #<\ /> # ~ s a l a d ~ P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 33 / 40

@dekoratory przekazywanie argumentów d ef a_decorator_passing_arguments ( f u n c t i o n _ t o _ d e c o r a t e ) : d e f a_wrapper_accepting_arguments ( arg1, arg2 ) : p r i n t " I got a r g s! Look : ", arg1, arg2 f u n c t i o n _ t o _ d e c o r a t e ( arg1, arg2 ) r e t u r n a_wrapper_accepting_arguments @ a_ decorator_ passing_ arguments d ef print_full_name ( first_name, last_name ) : p r i n t "My name i s ", first_name, last_name print_full_name ( " P e t e r ", "Venkman" ) # o u t p u t s : #I got a r g s! Look : P e t e r Venkman #My name i s P e t e r Venkman Przy dekoratorach stosowanych do dowolnych funkcji używa się *args, **kwargs. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 34 / 40

@dekoratory przekazywanie argumentów do dekoratora d ef wrap_in_tag ( tag ) : d e f f a c t o r y ( f u n c ) : d e f d e c o r a t o r ( args, kwargs ) : r e t u r n <%(tag ) s>%(r v ) s </%(tag ) s> % ({ tag : tag, r v : f u n c ( args, kwargs ) } ) r e t u r n d e c o r a t o r r e t u r n f a c t o r y @wrap_in_tag ( b ) @wrap_in_tag ( i ) d ef say ( v a l ) : r e t u r n v a l p r i n t say ( h e l l o ) Funkcja wrap_in_tag zwraca dekorator, który dokłada do wyniku dekorowanej funkcji zadany tag XML. P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 35 / 40

Klasy również można dekorować d ef addid ( o r i g i n a l _ c l a s s ) : o r i g _ i n i t = o r i g i n a l _ c l a s s. init d e f init ( s e l f, id, args, kws ) : s e l f. id = i d s e l f. g e t I d = g e t I d o r i g _ i n i t ( s e l f, args, kws ) o r i g i n a l _ c l a s s. init = init r e t u r n o r i g i n a l _ c l a s s @addid c l a s s Foo : pass P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 36 / 40

Metaklasy (Lasciate ogni speranza) Klasy są obiektami: klasy type new-style classes klasy types.classtype classic classes P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 37 / 40

Metaklasy (Lasciate ogni speranza) Klasy są obiektami: klasy type new-style classes klasy types.classtype classic classes W zasadzie nic nie stoi na przeszkodzie, aby klasy były obiektami dowolnej klasy (metaklasy). Jaki jest z tego pożytek? sianie zamętu i zniechęcenia kontrola tworzenia klasy (metody new i init ) kontrola tworzenia obiektów klasy (metoda call ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 37 / 40

Metaklasy c.d. Metaklasa danej klasy jest określona przez: atrybut metaclass metaklasa jednej z klas bazowych zmienna globalna metaclass types.classtype Tworzenie klasy skutkuje wywołaniem metaklasy: M( name, bases, d i c t ) gdzie: name nazwa klasy bases klasy bazowe dict elementy klasy P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 38 / 40

Metaklasy c.d. Przykład automatyczne tworzenie properties c l a s s autoprop ( t y p e ) : d e f init ( c l s, name, bases, d i c t ) : s u p e r ( autoprop, c l s ). init ( name, bases, d i c t ) p r o p s = {} f o r member i n d i c t. k e y s ( ) : i f member. s t a r t s w i t h ( "_get_" ) or member. s t a r t s w i t h ( "_set_" ) : p r o p s [ member [ 5 : ] ] = 1 f o r prop i n p r o p s. k e y s ( ) : f g e t = g e t a t t r ( c l s, "_get_%s " % prop, None ) f s e t = g e t a t t r ( c l s, "_set_%s " % prop, None ) s e t a t t r ( c l s, prop, p r o p e r t y ( f g e t, f s e t ) ) P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 39 / 40

Metaklasy c.d. Zastosowanie a = I n v e r t e d X ( ) a s s e r t not h a s a t t r ( a, "x" ) a. x = 12 a s s e r t a. x == 12 a s s e r t a. _InvertedX x == 12 P. Daniluk(Wydział Fizyki) PO w. XII Jesień 2013 40 / 40