O[X:] - us4us
Transkrypt
O[X:] - us4us
JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA Marcin Lewandowski [ [email protected] ] PROGRAMOWANIE FUNKCYJNE I OBIEKTOWE W PYTHONIE 2 PROGRAMOWANIE FUNKCYJNE 3 Źródła • Programowanie funkcyjne (wykład MIMUW) http://wazniak.mimuw.edu.pl/index.php?title =Programowanie_funkcyjne • M.L. Scott, Programming Language Pragmatics, Morgan Kaufmann, 3 ed., 2009 • Charming Python installments http://gnosis.cx/publish/tech_index_cp.html 4 Paradygmaty programowania • Proceduralne/Imperatywne – operacje wykonywane na danych (operacje zmieniają stan programu) • Obiektowe – opis interakcji pomiędzy obiektami • Funkcyjne – program jako funkcja 5 Imperatywne vs. Funkcyjne Cecha Imperatywne Funkcyjne Konstrukcja algorytmu Jakie instrukcje wykonad Jakie transformacje danych są (algorytm) i jak zmieniad stan potrzebne programu Zmiana/Stan programu Ważny Nie istnieje Kolejnośd wykonywania Ważna Mało ważna Przepływ sterowania Pętle, warunki i funkcje Funkcje, rekurencja Podstawowe elementy języka Struktury danych, instancje klas Funkcje jako obiekty ‘firstclass’, kolekcje danych (listy) 6 Konstrukcje programowania funkcyjnego w Pythonie • Funkcje jako obiekty podstawowe (tzw. first-class) – lambda, przekazywanie funkcji jako argument • Domknięcia (ang. Closures) – funkcje związane z damymi • Funkcje operujące na funkcjach (ang. high-order functions) • Dekoratory – forma opakowao (wrapperów) dla funkcji • Iteratory i Generatory • Listy jako podstawowa struktura danych (List Comprehensions) 7 Lambda • Lambda – proste, jednolinijkowe, anonimowe funkcje • Mogą byd przekazywane tak jak zwykłąe funkcje nazwane • Używane często jako funkcje w callback, list comprehesnsions, high-order functions • return jest w nich domniemany (implicite) square = lambda x: x*x >>> square(9) 81 squares = map(lambda x: x*x, range(3)) >>> squares [0, 1, 4] 8 Domknięcie (Closure) • Domknięcie to funkcja ze związanymi zmiennymi: – składa się z funkcji, jej lokalnych zmiennych oraz referencji do zmiennych spoza zakresu (outer scope) • Obiekty to metody związane z danymi na których działają; Domknięcia to dane dowiązane do funkcji # Zwraca funkcję opodatkowania daną stawką VAT def vat_taxer(rate): def taxer(amount): return amount * (float(rate) / 100) return taxer vat22 = vat_taxer(22) vat7 = vat_taxer(7) 9 Domknięcie przykład # zwraca funkcję mnożącą przez n def multiply_by(n): return lambda x: return x*n double = multiply_by(2) triple = multiply_by(3) >>> double(2) 4 >>> triple(4) 12 10 High-order functions – 1 • map – zastosuj funkcję na każdym elemencie sekwencji: >> map(lambda x: x**2, range(1,5)) [1, 4, 9, 16] • filter – wybiera elementy spełniające warunek >> filter(lambda x: x%2==0, range(10)) [0, 2, 4, 6, 8] • reduce – redukuje elementy sekwencji do jednej wartości za pomocą funkcji: >> reduce(lambda x,y: x+y, [1, 2, 3, 4]) 10 11 High-order functions – 2 • zip – zszywa kolejne elementy z sekwencji: >> zip((„a‟,‟b‟,‟c‟), (1,2,3)) [(„a‟,1), („b‟,2), („c‟,3)] • all – zwraca True, gdy wszystkie elementy są True: >> all((1, 2, „alala‟)) True • any – zwraca True, gdy choś jeden element jest True: >> any((0, None, 1)) True 12 Dekoratory def my_decorator(fn): def wrapper(*args): print “before invocation” fn(*args) print “after invocation” return wrapper @my_decorator def hello_world(): print “hello, world” >>> hello_world() before invocation hello, world after invocation 13 Iteratory • Iterator jest analogiem sekwencji ale z kilkoma różnicami: – Często używamy funkcji, która tworzy kolejne elementy sekwencji (np. za pomocą Generatora) – Elementy sekwencji są produkowane dopiero w momencie kiedy są potrzebne – Iteratory mogą tworzyd sekwencje dowolnie długie (w odróżnieniu od sekwencji struktur danych ograniczonych pamięcią) • Iterator to protokół (nie typ danych) na który składa się: – Funkcji next() (w implementacji __next__()) – Raise StopIteration after last item 14 Generatory • Generator – funkcja działająca jako Iterator • Każdy element jest zwracany za pomocą polecenia yield • Zakooczenie przez: – zakooczenie funkcji – zwykłe return – raise StopIteration 15 Generatory – przykład def four(): x = 0 while x < 3: print("in generator, x =", x) yield x x += 1 >>> for i in four(): print(i) in generator, x = 0 0 in generator, x = 1 1 in generator, x = 2 2 16 Generatory – wyrażenia • Składniowo podobne do List Comprehensions • Ewaluacja leniwa – jeden element za jednym razem • Mogą byd używane wszędzie, gdzie jest spodziewany Iterator # Przykład 1 it = (line.strip() for line in open('input.txt')) # Przykład 2 – można ominąć nawiasy w wywołaniu funkcji func(line.strip() for line in open('input.txt')) 17 EX9 3 implementacje is_prime() # Implementacja „imperatywna‟ – wersja 1 def is_prime(n): k = 2 while k < n: if n % k == 0: return False k += 1 return True # Implementacja „funkcyjna‟ – wersja 2 def is_prime(n): return len(filter(lambda k: n%k==0, range(2,n))) == 0 # Implementacja „funkcyjna‟ – wersja 3 def is_prime(n): return not any(n%k==0 for k in xrange(2,n)) 18 PROGRAMOWANIE OBIEKTOWE 19 Programowanie obiektowe Object-oriented programming (OOP) • Klasy i obiekty: – Obiekty są tworzone na podstawie definicji klas – Pojedynczy obiekt jest nazywany instancją klasy – Dane i operacje na nich (funkcje) tworzą obiekt • Operacje/funkcje zawarte w klasie są nazywane metodami • Dane/zmienne w klasie są nazywane atrybutami klasy • Atrybuty tworzą stan instancji klasy (obiektu) 20 Definicja klasy __init__ jest inicjalizatorem obiektu class circle: def __init__(self, radius): self.radius = radius self – jest referencją do obiektu # utworzenie obiektu klasy circle >> c = circle(10) c <__main__.circle instance at 0x004A48A0> >> dir(c) ['__doc__', '__init__', '__module__', 'radius'] 21 Przeszukiwanie: obiekt.atrybut • Szuka pierwszego wystąpienia atrybutu w obiekcie lub we wszystkich klasach powyżej (z których dziedziczył) – od dołu do góry i od lewej do prawej strony class C2: x=z=2 class C3: w=z=3 class C1(C2, C3): x=y=1 I1 = C1() I2 = C1() 22 Metody specjalne klas METODA IMPLEMENTUJE WOŁANA DLA __init__ Konstruktor obiektu X = Class(args) __del__ Destruktor obiektu Usuwanie obiektu X __add__ Operator + X + Y, X += Y jeśli nie __iadd__ __or__ Operator | (bitowy OR) X | Y, X |= Y jeśli nie _ior__ __repr__, __str__ Drukowanie, konwersja print(X), repr(X), str(X) __call__ Wywołanie funkcji X(*args, **kargs) __setattr__ Przypisanie atrybutu X.any = value __delattr__ Skasowanie atrybutu del X.any __getattribute__ Pobranie atrybutu X.any __getattr__ Pobranie atrybutu X.undefined 23 Metody specjalne klas c.d. METODA IMPLEMENTUJE WOŁANA DLA __getitem__ Indeksowanie, przecinanie, iteracja X[key], X[i:j], także dla pętli jeśli nie __iter__ __setitem__ Przypisanie indeksowane , przecinane X[key] = value, X[i:j] = sequence __delitem__ Usuwanie indeksowane, przecinane del X[key], del X[i:j] __len__ Długośd len(X), testowanie gdy nie __bool__ __bool__ Testy logiczne bool(X), (__nonzero__ w Py 2.6) __lt__, __gt__, __le__, __ge__, __eq__, __ne__ Porównania X < Y, X > Y, X <= Y, X >= Y, X == Y, X != Y (__cmp__ w Py 2.6) 24 Metody specjalne klas c.d. METODA IMPLEMENTUJE WOŁANA DLA __iadd__ Operator dodawania w miejscu X += Y __iter__, __next__ Iterator I=iter(X), next(I); dla pętli __contains__ Tester przynależności item in X (dla iterowalnych) __index__ Wartośd całkowitoliczbowa hex(X), bin(X), oct(X), O[X], O[X:] (zastpuje Py 2.x __oct__, __hex__) __enter__, __exit__ Menadżer kontekstu with with obj as var: __get__, __set__, __delete__ Deskryptory atrybutów X.attr, X.attr = value, del X.attr __new__ Tworzenie obiektu przed __init__ 25 Atrybuty specjalne klas • Wszystkie klasy posiadają następujące atrybuty: • • • • • • __doc__ – string dokumentacji __class__ – referencji do obiektu klasy (z każdej instancji) __bases__ – lista klas bazowych __name__ – nazwa klasy obiektu __module__ – nazwa modułu, w którym klasę zdefiniowano __dict__ – słownik będący przestrzenią nazw klasy (ale nie superklas) 26 Przykład 1 – zmienne klasowe class Circle: pi = 3.14159 # class variable def __init__(self, radius = 1): self.radius = radius def area(self): return self.radius**2 * pt print Circle.pi circle1 = Circle() print circle1.area() circle5 = Circle(5) print circle5.area() 27 Przykład 2 – metody statyczne class Circle: all_circles = [] # class variable pi = 3.14159 # class variable def __init__(self, r=1): self.radius = r self.__class__.all_circles.append(self) def area(self): return self.__class__.pi * self.radius * self.radius @staticmethod def total_area(): total = 0 for c in Circle.all_circles: total = total + c.area() return total 28 Przykład 3 – dziedziczenie class Shape: def __init__(self, x, y): self.x = x self.y = y class Square(Shape): def __init__(self, side=1, x=0, y=0): super().__init__(x, y) self.side = side class Circle(Shape): def __init__(self, r=1, x=0, y=0): super().__init__(x, y) self.radius = r 29 Przykład 4 – getters/setters class Temperature: def __init__(self): self.__t_fahr = 0 # private in F @property def temp(self): # in ºC return (self.__t_fahr-32)*5/9 @temp.setter def temp(self, new_temp): # in ºC self.__t_fahr = new_temp*9/5 + 32 30 EX10 Klasa operacji na ułamkach zwykłych • Implementacja klasy ułamek oraz operacji: – dodawania, odejmowania, mnożenia i dzielenia ułamków – wyświetlania ułamków 31