Zaawansowany Python / Luciano Ramalho. – Warszawa, 2015 Spis
Transkrypt
Zaawansowany Python / Luciano Ramalho. – Warszawa, 2015 Spis
Zaawansowany Python / Luciano Ramalho. – Warszawa, 2015 Spis treści Przedmowa xv Część I Prolog 1 Model danych Pythona Pythoniczna talia kart Sposoby używania metod specjalnych Emulacja typów liczbowych Reprezentacja tekstowa Operatory arytmetyczne Wartość Boolean typu niestandardowego Przegląd metod specjalnych Dlaczego len nie jest metodą Podsumowanie rozdziału Lektura uzupełniająca 3 4 8 9 11 12 12 13 14 15 16 Część II Struktury danych 2 Sekwencje i tablice Przegląd wbudowanych sekwencji Wyrażenia listowe i wyrażenia generatora Wyrażenia listowe a czytelność Wyrażenia listowe a funkcje map i filter Iloczyny kartezjańskie Wyrażenia generatora Krotki nie są jedynie niezmiennymi listami Krotki jako rekordy Rozpakowywanie krotek Rozpakowywanie zagnieżdżonych krotek Krotki nazwane Krotki jako niezmienne listy Wycinanie Dlaczego wycinki i zakresy wykluczają ostatni element Obiekty wycinków Wycinanie wielowymiarowe i wielokropki Przypisywanie do wycinków Używanie + i * z sekwencjami Budowanie listy list Przypisanie złożone w przypadku sekwencji 21 22 23 23 25 26 27 29 29 30 32 33 35 36 37 37 39 40 40 41 43 Zagadkowe przypisywanie += Metoda list.sort oraz wbudowana funkcja sorted Zarządzanie sekwencjami uporządkowanymi przy użyciu bisect Wyszukiwanie za pomocą funkcji bisect Wstawianie za pomocą funkcji bisect.insort Kiedy lista nie jest rozwiązaniem Tablice Widoki pamięci NumPy i SciPy Deques i inne kolejki Podsumowanie rozdziału Lektura uzupełniająca 44 46 48 48 51 52 52 56 57 60 64 65 3 Słowniki i zbiory Ogólne typy odwzorowujące Wyrażenia słownikowe Przegląd powszechnych metod odwzorowań Obsługa brakujących kluczy za pomocą setdefault Odwzorowania z elastycznym przeszukiwaniem kluczy defaultdict: inne podejście do brakujących kluczy Metoda _missing_ Odmiany dict Tworzenie klas podrzędnych klasy UserDict Niezmienne odwzorowania Teoria zbiorów Literały zbiorów Wyrażenia zbioru Operacje na zbiorach Budowa wewnętrzna typów dict i set Eksperyment wydajnościowy Tablice mieszające w słownikach Praktyczne konsekwencje działania słownika dict Jak działają zbiory - konsekwencje praktyczne Podsumowanie rozdziału Lektura uzupełniająca 71 72 74 75 77 79 79 81 84 85 87 88 90 91 92 96 96 98 101 104 105 105 4 Tekst a bajty Problemy ze znakami Podstawy bajtów Struktury i widoki pamięci Podstawowe kodery/dekodery Zrozumienie problemów kodowania/dekodowania Radzenie sobie z UnicodeEncodeError Radzenie sobie z UnicodeDecodeError Błąd SyntaxError podczas ładowania modułów z nieoczekiwanym 109 110 111 114 115 117 117 119 kodowaniem Jak wykryć kodowanie sekwencji bajtów BOM: przydatny gremlin Obsługa plików tekstowych Domyślne kodowanie: dom wariatów Normalizacje Unicode w celu rozsądniejszego porównywania Sprowadzanie do jednego rejestru Funkcje narzędziowe do dopasowywania normalizowanego tekstu „Normalizcja ekstremalna": usuwanie znaków diakrytycznych Sortowanie tekstu Unicode Sortowanie przy użyciu algorytmu porządku alfabetycznego Unicode Baza danych Unicode Dwutrybowe interfejsy API dla typów str i bytes str a bytes w wyrażeniach regularnych str a bytes w funkcjach modułu os Podsumowanie rozdziału Lektura uzupełniająca 120 122 122 124 127 130 133 134 135 138 140 141 143 143 144 147 148 Część III Funkcje jako obiekty 5 Funkcje pierwszej klasy Traktowanie funkcji jako obiektu Funkcje wyższego rzędu Nowoczesne odpowiedniki funkcji map, filter i reduce Funkcje anonimowe Siedem odmian obiektów wywoływalnych Definiowane przez użytkownika typy wywoływalne Introspekcja funkcji Od parametrów pozycyjnych do parametrów tylko słów kluczowych Pozyskiwanie informacji o parametrach Adnotacje do funkcji Pakiety do programowania funkcyjnego Moduł operator Zamrażanie argumentów przy użyciu funkcji functools.partial Podsumowanie rozdziału Lektura uzupełniająca 155 156 157 158 160 161 162 163 165 167 172 174 174 178 180 181 6 Wzorce projektowe z funkcjami pierwszej klasy Studium przypadku: refaktoryzacja wzorca Strategia Klasyczny wzorzec Strategia Strategia zorientowana funkcyjnie Wybieranie najlepszej strategii: proste podejście Znajdowanie Strategii w module Polecenie Podsumowanie rozdziału 185 186 186 190 193 194 196 197 Lektura uzupełniająca 198 7 Dekoratory funkcji i domknięcia Dekoratory 101 Kiedy Python wykonuje dekoratory Wzorzec Strategia wzbogacony dekoratorem Reguły zasięgów zmiennych Domknięcia Deklaracja nonlocal Implementacja prostego dekoratora Sposób działania Dekoratory w bibliotece standardowej Memoizacja dzięki functools.lru_cache Funkcje generyczne z pojedynczym rozsyłaniem Zagnieżdżanie dekoratorów Dekoratory parametryzowane Parametryzowany dekorator rejestrujący Parametryzowany dekorator Clock Podsumowanie rozdziału Lektura uzupełniająca 201 202 203 205 207 210 213 215 216 218 219 221 224 225 226 228 230 231 Część IV Idiomy zorientowane obiektowo 8 Odwołania do obiektów, zmienność i odzyskiwanie pamięci Zmienne nie są pudełkami Tożsamość, równość i aliasy Wybór między == a is Względna niezmienność krotek Kopie są domyślnie płytkie Głębokie i płytkie kopie arbitralnych obiektów Parametry funkcji jako odwołania Typy zmienne jako domyślne parametry: zły pomysł Programowanie obronne ze zmiennymi parametrami del i odzyskiwanie pamięci Słabe odwołania Skecz WeakValueDictionary Ograniczenia słabych odwołań Trikowe gry Pythona z niezmiennymi obiektami Podsumowanie rozdziału Lektura uzupełniająca 237 238 240 241 242 243 246 247 249 251 253 255 256 258 259 261 262 9 Obiekt pythonowy Reprezentacje obiektów Przypomnienie klasy Vector Alternatywny konstruktor 267 268 268 271 classmethod a staticmethod Formatowane wyświetlanie Haszowalny obiekt Vector2d Prywatne i „chronione" atrybuty w Pythonie Oszczędzanie miejsca dzięki atrybutowi klasy _slots_ Problemy z atrybutem _slots_ Przesłanianie atrybutów klasy Podsumowanie rozdziału Lektura uzupełniająca 272 274 277 283 285 288 288 291 292 10 Kodowanie, haszowanie i wycinanie sekwencji Vector: definiowany przez użytkownika typ sekwencyjny Vector podejście nr 1: zgodność z Vector2d Protokoły i kacze typowanie Vector podejście nr 2: sekwencja z możliwością wycinania Działanie wycinania Metoda _getitem_ świadoma wycinania Vector podejście nr 3: dynamiczny dostęp do atrybutów Vector podejście nr 4: haszowanie i szybsze == Vector podejście nr 5: formatowanie Podsumowanie rozdziału Lektura uzupełniająca 297 298 298 301 302 303 305 307 311 316 324 325 11 Interfejsy: od protokołów do abstrakcyjnych klas bazowych Interfejsy i protokoły w kulturze języka Python Python lubi sekwencje Małpie łatanie w celu zaimplementowania protokołu w trakcie działania programu Wodne ptactwo Alexa Martelli Tworzenie podklasy z abstrakcyjnej klasy bazowej Abstrakcyjne klasy bazowe w bibliotece standardowej Abstrakcyjne klasy bazowe w collections.abc Wieża liczbowa klas ABC Definiowanie i wykorzystywanie abstrakcyjnej klasy bazowej Szczegóły składni abstrakcyjnych klas bazowych Tworzenie podklas dla abstrakcyjnej klasy bazowej Tombola Wirtualna podklasa klasy Tombola Jak testowano podklasy klasy Tombola Użycie metody register w praktyce Gęsi mogą zachowywać się jak kaczki Podsumowanie rozdziału Lektura uzupełniająca 331 332 334 336 338 344 346 346 348 349 354 355 357 360 363 364 365 368 12 Dziedziczenie: na dobre czy na złe Tworzenie klas podrzędnych z typów wbudowanych jest zawiłe 375 376 Wielokrotne dziedziczenie i kolejność ustalania metod Wielokrotne dziedziczenie w świecie rzeczywistym Radzenie sobie z wielokrotnym dziedziczeniem 1. Rozróżniać dziedziczenie interfejsów od dziedziczenia implementacji 2. Tworzyć jawne interfejsy przy pomocy klas ABC 3. Korzystać z domieszek w celu ponownego wykorzystania kodu 4. Jawnie deklarować domieszki dzięki nazewnictwu 5. Klasa ABC może być też domieszką, ale nie na odwrót 6. Nie tworzyć podklasy dziedziczącej z więcej niż jednej klasy konkretnej 7. Dostarczać użytkownikom klasy łączone 8. „Preferować komponowanie obiektów przed dziedziczeniem klas" Tkinter: dobry, zły i brzydki Nowoczesny przykład: domieszki w ogólnych widokach Django Podsumowanie rozdziału Lektura uzupełniająca 379 384 387 387 387 387 388 388 388 389 389 390 391 394 395 13 Przeciążanie operatorów: rób to poprawnie Podstawy przeciążania operatorów Operatory unarne Przeciążanie operatora + w celu zaimplementowania dodawania wektorów Przeciążanie operatora * dla mnożenia wektora przez wartość skalarną Bogate operatory porównania Operatory rozszerzonego przypisania Podsumowanie rozdziału Lektura uzupełniająca 399 400 400 403 409 413 418 423 424 Część V Przepływ sterowania 14 Iterowalność, iteratory i generatory Klasa Sentence - podejście nr 1: sekwencja słów Dlaczego sekwencje są iterowalne: funkcja iter Obiekty iterowalne a iteratory Klasa Sentence - podejście nr 2: klasyczne wnętrze Klasa Sentence jako iterator: zły pomysł Klasa Sentence - podejście nr 3: funkcja generatora Jak działa funkcja generatora Klasa Sentence - podejście nr 4: leniwa implementacja Klasa Sentence - podejście nr 5: wyrażenie generatora Wyrażenia generatora: kiedy ich używać Inny przykład: generator ciągu arytmetycznego Ciąg arytmetyczny wykorzystujący itertools Funkcje generatora w bibliotece standardowej Nowa składnia w wersji Python 3.3: yield from Funkcje redukujące obiekty iterowalne 431 432 434 436 440 441 442 443 447 448 450 451 453 455 467 468 Bliższe przyjrzenie się funkcji iter Studium przypadku: generatory w narzędziu do konwersji baz danych Generatory jako współprogramy Podsumowanie rozdziału Lektura uzupełniająca 470 471 473 474 474 15 Zarządzanie kontekstem i bloki else Zrób to, potem tamto: bloki else poza instrukcją if Zarządzanie kontekstem i bloki with Narzędzia contextlib Korzystanie z @contextmanager Podsumowanie rozdziału Lektura uzupełniająca 481 482 484 489 489 493 494 16 Współprogramy Jak współprogramy wyewoluowały z generatorów Podstawowe zachowanie generatora zastosowane jako współprogram Przykład: współprogram obliczający średnią kroczącą Dekoratory przygotowujące współprogram Kończenie współprogramów i obsługa wyjątków Zwracanie wartości ze współprogramu Korzystanie z yield from Znaczenie konstrukcji yield from Przypadek użycia: współprogramy dla dyskretnego symulowania zdarzeń Symulacje zdarzeń dyskretnych Symulacja floty taksówek Podsumowanie rozdziału Lektura uzupełniająca 497 498 499 503 504 506 510 512 519 17 Współbieżność z futures Przykład: pobieranie stron WWW na trzy sposoby Skrypt pobierania sekwencyjnego Pobieranie przy pomocy concurrent.futures Gdzie są obiekty future? Blokowanie wejścia/wyjścia a GIL Uruchamianie procesów przy pomocy concurrent.futures Eksperymentowanie z Executor.map Pobierania flag z wyświetlaniem postępów i obsługą błędów Obsługa błędów w przykładach flags2 Korzystanie z futures.as_completed Alternatywy dla przetwarzania wielowątkowego Podsumowanie rozdziału Lektura uzupełniająca 543 544 546 548 549 553 554 556 559 564 566 569 570 571 525 525 526 535 536 18 Współbieżność z asyncio Wątek kontra współprogram: porównanie Klasa asyncio.Future: nieblokująca z założenia Instrukcja yield from a obiekty future, zadania i współprogramy Pobieranie obrazów przy pomocy asyncio i aiohttp Bieganie w kółko wokół wywołań blokujących Ulepszanie skryptu pobierającego obrazy wykorzystującego asyncio Wykorzystanie asyncio.as_completed Korzystanie z obiektu wykonawczego w celu uniknięcia zablokowania pętli zdarzeń Od procedur zwrotnych do obiektów future i współprogramów Wykonywanie wielu żądań dla każdego pobierania Pisanie serwerów wykorzystujących asyncio Serwer TCP wykorzystujący asyncio Serwer WWW wykorzystujący aiohttp Inteligentniejsi klienci a lepsza współbieżność Podsumowanie rozdziału Lektura uzupełniająca 577 579 585 586 588 593 595 596 601 603 605 608 609 614 617 618 619 Część VI Metaprogramowanie 19 Atrybuty i właściwości dynamiczne Przekształcanie danych przy pomocy atrybutów dynamicznych Badanie danych przypominających JSON przy pomocy atrybutów dynamicznych Problem z nieprawidłowymi nazwami atrybutów Elastyczne tworzenie obiektów przy pomocy _new_ Restrukturyzacja źródła danych OSCON przy pomocy shelve Pobieranie połączonych rekordów przy pomocy właściwości Użycie właściwości do sprawdzania poprawności atrybutów LineItem - podejście nr 1: klasa dla elementu zamówienia LineItem - podejście nr 2: właściwość sprawdzająca swoją poprawność Właściwe spojrzenie na właściwości Właściwości przesłaniają atrybuty instancji Dokumentacja właściwości Kodowanie fabryki właściwości Obsługiwanie usuwania atrybutów Podstawowe atrybuty i funkcje obsługujące atrybuty Atrybuty specjalne, które wpływają na obsługę atrybutów Funkcje wbudowane do obsługi atrybutów Metody specjalne do obsługi atrybutów Podsumowanie rozdziału Lektura uzupełniająca 627 628 631 634 635 637 641 647 647 648 650 651 654 655 658 659 659 660 661 662 663 20 Deskryptory atrybutów 669 Przykład deskryptora: sprawdzanie poprawności atrybutu LineItem podejście nr 3: prosty deskryptor LineItem podejście nr 4: automatyczne nazwy atrybutów przechowywania LineItem podejście nr 5: nowy typ deskryptora Deskryptory przesłaniające a nieprzesłaniające Deskryptor przesłaniający Deskryptor przesłaniający bez _get_ Deskryptor nieprzesłaniający Nadpisywanie deskryptora w klasie Metody są deskryptorami Wskazówki dotyczące użycia deskryptorów Dokumentacja docstring deskryptora i przesłanianie usuwania Podsumowanie rozdziału Lektura uzupełniająca 669 670 675 681 684 686 687 688 689 690 693 694 695 696 21 Metaprogramowanie klas Fabryka klas Dekorator klasy służący do dostosowywania deskryptorów Co dzieje się kiedy: czas importu a czas działania Ćwiczenia dotyczące czasu przetwarzania Metaklasy 101 Ćwiczenie dotyczące czasu przetwarzania metaklasy Metaklasa do dostosowywania deskryptorów Metoda specjalna _prepare_metaklasy Klasy jako obiekty Podsumowanie rozdziału Lektura uzupełniająca 699 700 703 706 707 710 713 717 719 721 722 723 Posłowie 727 Dodatek: Skrypty pomocnicze 731 Żargon społeczności Pythona 759 Indeks 769 O autorze 788 oprac. BPK