Scott Tiger Tech Blog

Blog technologiczny firmy Scott Tiger S.A.

Python

Autor: Piotr Karpiuk o niedziela 3. Październik 2010

Python jest popularnym, bogatym w biblioteki, opensource’owym, interpretowanym, obiektowym, skryptowym językiem programowania o blisko 20-letniej historii. Wykorzystywany szeroko przez firmy takie jak Google, Yahoo!, CERN czy NASA (w tej pierwszej pracuje twórca języka, holenderski programista Guido van Rossum). Dostępny na prawie każdym systemie operacyjnym, a nawet na JVM (Jython) i .NET (Iron Python). Jest językiem ogólnego przeznaczenia i można w nim pisać aplikacje GUI (np. dla Qt przy użyciu biblioteki PyQT), ale często jest postrzegany jako język skryptowy dla aplikacji webowych – to w Pythonie zaimplementowane są popularne frameworki takie jak Django, Pylons, TurboGears, web2py, czy Zope.

Cechy charakterystyczne Pythona 3.x z lotu ptaka to m.in.:

  • wszystko jest obiektem (również liczba całkowita, funkcja, moduł itp.) i ma swoją klasę; dostępne są m.in. wielodziedziczenie i klasy abstrakcyjne,
  • bardzo rozbudowane mechanizmy refleksji i metaprogramowania (oprócz klasycznego eval() można np. tworzyć w locie klasy i metaklasy, dodawać metody do istniejących klas, atrybuty do istniejących obiektów, a dostęp do atrybutów – nawet nieistniejących – może być przechwytywany),
  • do wyznaczania bloków kodu wykorzystuje wcięcia wierszy (!), co wpływa na estetykę źródeł,
  • można przedefiniowywać operatory,
  • bardzo elastyczny mechanizm przekazywania parametrów do funkcji/metody (pozycyjnie, po nazwie, możliwe przyjęcie dowolnej liczby parametrów, adnotacje – patrz dalej, itp.),
  • funkcja jest bytem pierwszego rzędu (może być przekazywana jako parametr, zwracana jako wynik funkcji), dostępne są domknięcia oraz całkiem pokaźny arsenał technik programowania funkcyjnego (funkcje anonimowe, mapowanie, filtrowanie, redukcja, funkcje częściowe) – o czym będzie dalej,
  • współprogramy (ang. coroutines) pozwalające tworzyć generatory leniwie wyliczające kolejne elementy iteracji oraz potoki przetwarzania danych przypominające potoki w UNIXowej powłoce,
  • dekoratory funkcji i klas: dekorator jest funkcją która pobiera dekorowany obiekt (np. funkcję), wzbogaca go/modyfikuje i zwraca – co nawiązuje do idei programowania aspektowego (przykład: dekorator który loguje nazwę, parametry wywołania i wynik wykonania dekorowanej funkcji),
  • a ponadto obsługa wyjątków, dynamiczne typowanie, garbage collector i ogólnie to wszystko co mają inne współczesne języki skryptowe.

Ciekawostki składniowe które być może zachęcą kogoś do spojrzenia na język łaskawym okiem:

Segmentacja

moja_lista[3:10:2]
zwraca listę: co drugi element wycinka 3..9 listy moja_lista
moja_lista[::-1]
zwraca odwróconą listę


Listy/zbiory/słowniki składane (ang. list/set/dict comprehension)

[y for y in range(1900, 1940) if y % 4 == 0]
zwraca listę lat przestępnych z podanego zakresu
{x for x in os.listdir(".") if x.lower().endswith((".htm", ".html"))}
zbiór nazw tych plików, które zawierają HTML
{nazwa: os.path.getsize( nazwa ) for nazwa in os.listdir(".") if os.path.isfile(nazwa)}
słownik nazwa_pliku -> wielkość pliku dla wszystkich plików (ale nie katalogów) w bieżącym katalogu

Elementy funkcyjne

functools.reduce(operator.add, map(os.path.getsize, filter(lambda x: x.endswith(".py"), os.listdir("."))))
zwraca rozmiar w bajtach wszystkich plików źródłowych Pythona w bieżącym katalogu
sum(os.path.getsize(x) for x in os.listdir(".") if x.endswith(".py"))
to samo, ale jeszcze krócej

Sygnatury funkcji

def ask_ok(prompt, retries=4, complaint="Yes or no, please!" *args **keywords)
Można definiować funkcje przyjmujące dowolną ilość argumentów. W tym przykładzie zmienna args jest krotką na którą zostaną przypisane wszystkie nadmiarowe argumenty pozycyjne, a keywords jest słownikiem zawierającym wszystkie argumenty nazwane nie mające odpowiedników w parametrach formalnych. Można wołać np. ask_ok("OK to overwrite?", 2), ask_ok("OK to overwrite?", complaint="Tak lub Nie", misio=24)
def ask_ok( prompt : str, retries : int) -> bool
Każdy dwukropek z wyrażeniem stanowi opcjonalną adnotację, podobnie jak strzałka i następujące po niej wyrażenie zwrotne. Adnotacje są dodawane do słownika __annotations__ funkcji. Kluczem jest tu nazwa parametru, wartością odpowiadające mu wyrażenie. Jedynym krokiem podejmowanym przez Pythona w stosunku do adnotacji jest umieszczenie ich w słowniku __annotations__, wszelkie pozostałe działania należą do programisty. Może on np. założyć że wyrażenia będą oznaczały typ i stworzyć dekorator który będzie weryfikował typy parametrów wywoływanej funkcji.

Generatory
Funkcja generatora lub metoda generatora to taka, która zawiera wyrażenie yield. Podczas wywoływania funkcji generatora wartością zwrotną jest iterator. Generatory wykonują rodzaj leniwych obliczeń, tzn. obliczają jedynie te wartości, które są potrzebne w danej chwili – takie rozwiązanie może być znacznie efektywniejsze niż np. jednorazowe wygenerowanie ogromnej listy, tym bardziej gdy lista taka musiałaby być nieskończona:

      def ciag_potegowy(y=0.0):
        while True:
          yield y
          y *= y

Przykład użycia generatora:

      wynik = []
      for x in ciag_potegowy():
        wynik.append(x)
        if x >= 1500:
          break

Funkcja generatora jest przykładem użycia współprogramu (ang. coroutine). Współprogram można zawiesić poleceniem yield w oczekiwaniu aż zwróci ono wynik, po czym kontynuuje działanie. W ten sposób można przekazywać zadania do wykonania oraz tworzyć potoki przetwarzania danych.

Wyrażenie generatora pod względem syntaktycznym jest niemal identyczne z listą składaną, różnica polega na ujęciu go w nawiasy okrągłe zamiast kwadratowych.

def elementy_w_kolejnosci_klucza( d ):
  for klucz in sorted(d):
    yield klucz, d[klucz]

To jest to samo co:

def elementy_w kolejnosci_klucza( d ):
  return ((klucz, d[klucz]) for klucz in sorted(d))
Python, 4.0 out of 5 based on 1 rating
Share and Enjoy:
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Śledzik
  • Blip
  • Blogger.com
  • Gadu-Gadu Live
  • LinkedIn
  • MySpace
  • Wykop

Zostaw komentarz

XHTML: Możesz użyć następujących tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>