Your SlideShare is downloading. ×
0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Pycrashcourse3.0
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Pycrashcourse3.0

260

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
260
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. Introduzione alLinguaggio PythonEnrico Franchiefranchi@ce.unipr.itDipartimento di Ingegneria dellInformazioneUniversità di Parma 1
    • 2. Parlando delfuturo... 2We will perhaps eventually bewriting only small modules that areidentified by name as they areused to build larger ones, so thatdevices like indentation, rather thandelimiters, might become feasiblefor expressing local structure in thesource language.Donald E. Knuth, StructuredProgramming with go toStatements, 1974
    • 3. Introduzione 3 Python è concepito da Guido van Rossum alla fine degli anni ‘80 per Amoeba Pubblico 1991, stabile 1994. Linguaggio di alto livello ed orientato agli oggetti. Utilizzato per programmazione di sistema e di rete, e calcolo scientifico, applicazioni desktop, integrazione di videogiochi Si impone in ambito web/enterprise, con soluzioni come Zope/Plone, Django e Twisted.
    • 4. Piattaforma Python 4 “Very high-level language” (VHLL): sintassi pulita e scarna semantica semplice, regolare, potente object-oriented, ma multi-paradigma produttività tramite: modularità, uniformità, semplicità, pragmatismo Offre una ricca libreria standard di moduli Tanti strumenti ed estensioni di terze-parti Implementazioni in C, Java, .NET e Python stesso
    • 5. Comunità Python 5Una forte comunità open-sourceMolti utenti (individui e compagnie) in tutti i campiPython Software Foundation (in Italia, Python Italia)Gruppi d’interesse per argomenti specificiSiti web, newsgroup, mailing list, ...Corsi, laboratori, tutorial, conferenze (Pycon Italia,quattro edizioni, fra le maggiori conferenze open italiana) Molti (specialmente in inglese...) in linea, su carta, o entrambi
    • 6. MESSAGGIO PROMOZIONALE 6 7-8-9 MAGGIO 2010 FIRENZESCONTO STUDENTI, SESSIONI RECRUITING, ETC ETC http://www.pycon.it ~400 partecipanti
    • 7. Tempi di Apprendimento 7Tempi necessari a un programmatore esperto perimparare bene...: Python vero e proprio (il linguaggio Python): 1-3 giorni builtin, metodi speciali, metaprogramming, ecc: 2-4 giorni la libreria standard (moduli fondamentali: os, sys, re, struct, itertools, collections, array, atexit, math, pickle, StringIO, heapq, weakref, threading...): 10-15 giorni tutta la libreria std: 30-50 giorni
    • 8. Python da 3000 metri (1) 8 Python è un linguaggio ad oggetti a tipizzazione dinamica e forte Tipizzazione forte: Gli errori di tipo sono sempre generati. Es. Stringhe non diventano interi e viceversa Ogni oggetto ha una classe, questa non cambia Tipizzazione dinamica Gli errori di tipo sono generati a runtime Duck typing
    • 9. Python da 3000 metri (II) 9 In Python tutto è un oggetto: Un numero, una stringa sono oggetti Gli oggetti sono oggetti (ehm...) Una funzione è un oggetto Una classe è un oggetto Gli oggetti sono cittadini di prima classe, possiamo manipolarli riccamente e comodamente (introspezione, etc.) Possiamo fare, in definitiva, tutto
    • 10. Versioni 10 Python è notevolmente compatibile fra versioni diverse Gli esempi di queste slides funzioneranno con Python 2.5 o Python 2.6, a meno che altrimenti specificato La maggior parte funzioneranno anche con Python 2.4 e Python 2.3 Python 3.x rappresenta il futuro, ma per ora si utilizza ancora 2.x, la transizione sarà morbida e lunga anni
    • 11. Hello, world! 11 print
“Hello,
world!”
    • 12. Dettagli implementativi 12 % cat hello.py Tipicamente Python viene #!/usr/bin/python compilato a byte-code e questo viene interpretato da print "Hello, world!" una macchina virtuale (come % python hello.py Java) Hello, world! Diversamente da Java la % chmod 755 hello.py % ./hello.py compilazione è trasparente Hello, world! per l’utente % python Python 2.5.1 (...) Possiamo anche usare ... l’interprete interattivo >>> print "Hello, world" Hello, world
    • 13. Interprete interattivo 13 L’interprete interattivo ufficiale ha >>> import os come prompt >>> >>> print “foo” foo Scriviamo comandi (statements) >>> os.getcwd() “/Users/enric/pycourse” che vengono byte-compilati ed >>> import sys >>> sys.stdout.write(“ciaon”) eseguiti ciao >>> def f(a): Se il comando valuta in un ... sys.stdout.write(a) ... return a espressione (es. un expression ... statement), l’espressione viene >>> f(“ciaon”) ciao stampata “ciaon”
    • 14. Letterali 14 >>> 12 >>> 3.2E10 Numeri interi, float 12 32000000000.0 >>> -27 >>> ciao Base 10, 8, 16 -27 ciao >>> 0x6A >>> "ciao" Scientifica, fixpoint 106 ciao >>> 0.216 >>> c 0.216 c Stringhe >>> [1, 2, "a", 2.32, "ciao"] Apici singoli o doppi [1, 2, a, 2.3199999999999998, ciao] >>> Testo con Tre apici per testo multilinea ... piu linee ... di testo Liste "Testo connpiu lineendi testo" >>> """Ancora testo con ... piu linee di testo""" Fra quadre, separate da "Ancora testo connpiu linee di testo" virgola
    • 15. a = 16 print a a = 7.6Variabili print a print a * 2 a = ciao 15 i=1 In Python una variabile è print i, type(i) semplicemente un nome, un’ # => 1 <type int> d = 217.217 etichetta, un modo per print d, type(d) # => 217.217 <type float> riferirsi ad un oggetto s = Solito testo su piu righe Le variabili non hanno tipo, print s, type(s) # => Solito testo gli oggetti hanno tipo # su piu righe <type str> d=2 Una etichetta può riferirsi ad print d, type(d) # => 2 <type int> oggetti di diverso tipo nel i = 32761293836219387269827 print i, type(i) tempo # => 32761293836219387269827 <type long> Assegnamento è statement
    • 16. Variabili/Oggetti 16 [java] Pet fido = new Dog();tipo a compile-time tipo a runtime oggetto (dell’oggetto) (della variabile) variabile [python] fido = Dog()
    • 17. Controllo di flusso 17 Condizionale: Su if c’è poco da dire; while si if cond: usa rarissimamente, grazie ai statement else: generatori si preferisce for statement Siccome l’assegnamento è uno if cond: statement statement, non è possibile Iterazione unbounded: metterlo come condizione while cond: statement (fortunatamente)else: Disponibili break/continue statement else di for/while esegue suwhile cond: statement terminazione naturale (no exc/ cont/break/return)
    • 18. Liste (I) 18 >>> a = [1, 2, a, ciao, 4] La lista è in realtà un vector: >>> a[0] 1 accesso O(1) agli elementi >>> a[3] ciao Inserimento e rimozione in >>> a[-1] 4 coda O(1) >>> a[10] Traceback (most recent call last): Controllo sugli indici File "<stdin>", line 1, in <module> IndexError: list index out of range (IndexError) >>> a.append(3) >>> a Indici negativi contano a [1, 2, a, ciao, 4, 3] >>> l = range(1, 4) partire dal fondo >>> a.extend(l) >>> a Possibilità di slice [1, 2, a, ciao, 4, 3, 1, 2, 3] >>> a.pop() 3
    • 19. Liste (II) 19 >>> a Presenti anche: [1, 2, a, ciao, 4, 3, 1, 2] >>> a[1:4] insert(i, o): inserisci o in [2, >>> a, ciao] a[1:8:2] posizione i [2, ciao, 3, 2] >>> a[::-1] remove(v): togli la prima [2, 1, 3, 4, ciao, a, 2, 1] >>> a occorrenza di v [1, 2, a, ciao, 4, 3, 1, 2] count(v): ... index(v): ... sort(): ... ... Le liste sono mutabili
    • 20. Tuple 20 >>> t = tuple(a) “Simili” alle liste, tuttavia non >>> t[3] ciao sono mutabili >>> t[-1] 2 Non possiamo aggiungere >>> t[1:] (2, a, ciao, 4, 3, 1, 2) elementi >>> a, b, c = t[:3] >>> print a, b, c Non possiamo cambiare 1 2 a elementi nella tupla >>> t = 1, 2, x >>> l = list(t) Possiamo agire su questi, se >>> t.append(5) Traceback (most recent call last): non sono immutabili File "<stdin>", line 1, in <module> AttributeError: tuple object has no attribut Per il resto funziona tutto >>> l.append(5) >>> l come previsto [1, 2, x, 5]
    • 21. Stringhe 21 Anche le stringhe sono >>> s = Hello, world! >>> s.strip() immutabili (= Java, != C++) Hello, world! >>> s.replace(o, 0) Hell0, w0rld! Supportano slicing, indexing, >>> s.find(o) etc. 4 >>> s.rfind(o) 8 isdigit(), ... >>> s.upper() HELLO, WORLD! strip()... >>> s.center(60) Hello, world! find/rfind/index/rindex(ch) >>> s.startswith(He) True >>> s.split(, ) startswith/endswith(s) [Hello, world! ] upper/lower/capitalize() ... andate a guardarli tutti!
    • 22. Operazioni su sequenze 22 >>> s = ciao Stringhe, tuple e liste sono >>> m = mondo >>> min(s) # <= a sequenze >>> max(m) # <= o >>> l = [1, 2, 3] Tutte le sequenze supportano >>> sum(l) # <= 6 >>> s + m # <= ciaomondo alcune operazioni >>> s + l Traceback (most recent call last): min/max/sum File "<stdin>", line 1, in <module> TypeError: cannot concatenate str and list >>> list(s) + l + : concatenazione [c, i, a, o, 1, 2, 3] >>> = * 10 S * n/ n * S: ripetizione ========== >>> [1, ] * 10 el in S: appartenenza [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] >>> a in s True >>> pippo in l False
    • 23. Attenzione! 23 Sommare tanti oggetti immutabili funziona, ma crea ogni volta un nuovo elemento: Sommare 10 stringhe crea 10 nuove stringhe. E se sono 10000? Potrebbe essere l’ultimo pezzo di codice prima del licenziamento. Si usa join nella forma sep.join(elements) >>> lst = [usr, local, lib] >>> /.join(lst) usr/local/lib >>> => .join(lst) usr => local => lib Per concatenare pezzi di path, usare os.path.join e i metodi presenti in os.path
    • 24. Statement For 24 For è il modo più comune di for ch in ciao mondo: print ch, iterare in Python print for n in range(10): Funziona con un generico print n iterabile for n in xrange(10): print n Esprime il concetto di “per for n in range(1, 20): ogni elemento in questa print n for n in xrange(1, 10000000000): sequenza” fai qualcosa print n Invece che usare una sequenza (finita), possiamo usare un generatore (potenzialmente infinito)
    • 25. Statement For 24 For è il modo più comune di for ch in ciao mondo: print ch, iterare in Python print for n in range(10): Funziona con un generico print n iterabile for n in xrange(10): print n Esprime il concetto di “per for n in range(1, 20): ogni elemento in questa print n for n in xrange(1, 10000000000): sequenza” fai qualcosa print n Invece che usare una sequenza (finita), possiamo Attenzione! range ritorna usare un generatore una lista xrange un iteratore. (potenzialmente infinito) Restituiscono intervalli [a, b)
    • 26. 99 Bottles of Beer 25def pluralize(s, quantity): if quantity == 1: return s else: return s + "s"for how_many in range(99, 0, -1): print how_many, pluralize("bottle", how_many), "on the wall!" print "Take one down and pass it around,", how_many-1, print pluralize("bottle", how_many-1), print "of beer on the wall."
    • 27. More on for... 26 import os import shutil for fname in os.listdir(os.getcwd()): if fname.endswith((pyc, pyo)): os.remove(fname) elif fname.endswith(py): shutil.copy(fname, fname + .bak)
    • 28. Dizionari 27 Array associativi/dizionari: >>> d = {foo : (1, 2, 3), ... bar : (2, 3, 4)} coppie chiave-valore >>> d[foo] (1, 2, 3) Operazioni tipicamente O(1) >>> d[baz] Traceback (most recent call last): File "<stdin>", line 1, in <module> Implementazione KeyError: baz esageratamente efficiente >>> d[bar] = foo >>> d {foo: (1, 2, 3), bar: foo} La chiave deve essere hashabile e immutabile (ecco perchè le stringhe...) Essenzialmente è una hash- table
    • 29. Dizionari (altri metodi) 28 D.pop(k[, d]): rimuove k (se presente) restituendo il valore corrispondente. Altrimenti restituisce d se specificato o da AttributeError D.popitem(): ritorna una coppia k-v (qualsiasi) D.get(k[,d]): ritorna il valore di k o d se k non è presente. Se non specificato d vale None. D.setdefault(k[,d]): D.get(k,d), setta D[k]=d se k non è in D D.update(E, **F): aggiunge le coppie k-v di E (ed F) a D
    • 30. Format (printf-on-steroids) 29 Le stringhe hanno un operatore % che permette di fare “format string” simili alla printf del C. -- man printf -- stringa % tupla: sostituzione posizionale: >>> %s %d %s % (ciao, 9, (h, p)) "ciao 9 (h, p)" stringa % dizionario: sostituzione per nome: >>> Mi chiamo %(surname)s, %(fname)s %(surname)s. % {surname: Bond, fname : James} Mi chiamo Bond, James Bond. Estremamente comodo. Usando %s si passa per str(obj), usando %r per repr(obj)
    • 31. Esempio dizionari 30 import sys filename = sys.argv[1] indx = {} try: f = open(filename) for n, line in enumerate(f): for word in line.split(): indx.setdefault(word, []).append(n) finally: f.close() for word in sorted(indx): # indice alfabetico print "%s:" % word, for n in indx[word]: print n, print
    • 32. I/O elementare 31 due funzioni built-in per linput elementare input(prompt): immette qualsiasi espressione -- ne torna il valore raw_input(prompt): torna una stringa, rimuove il n a fine stringa un’istruzione per loutput elementare print <0+ espressioni separate da virgole> separa i risultati con uno spazio n alla fine (ma non se terminate con virgola) print di suo non fa formattazioni speciali print >> writable, <0+ espressioni separate da virgole>
    • 33. Eccezioni 32 Errori (e “anomalie” che non sono errori) “sollevano eccezioni” L’istruzione raise solleva un’eccezione Le eccezioni si propagano “lungo lo stack delle chiamate”, man mano terminando le funzioni, sinchè non vengono “catturate” Se non catturate, terminano il programma Listruzione try/except può catturare eccezioni (anche: try/finally, e lelegante with per implementare “RAII”)
    • 34. LBYL vs. EAFP 33LBYL: Look before you leap # LBYL -- cattivo if user_name in employees:EAFP: Easier to ask forgiveness emp =than permission employees[user_name] else:Normalmente EAFP è la report_error(...)strategia migliore in Python Eccezioni relativamente poco costose #EAFP -- buono try: Atomicità, ... emp = employees[user_name] except KeyError: report_error(...)
    • 35. Vari tipi di try 34try: # codice che potrebbe lanciare eccezioneexcept IndexError, exc: # un tipo di errore # opzionalmente si mette ‘, nome’ per avere # l’oggetto eccezione da gestireexcept AnotherException: # gestione di un altro erroreexcept: # gestione di ogni eccezione # tipicamente *NON* e una buona pratica # a meno di non rilanciare raise # raise vuoto rilancia leccezione correntefinally: # questo codice e eseguito *sempre* # codice di pulizia sia con errore che senza
    • 36. List Comprehensions 35“Matematichese”: { f (x) | ∀x ∈S tali che p(x)}Python: [f(x) for x in seq if p(x)] Lista di tutti gli f(x) per tutti gli x contenuti in seq, a patto che p(x) sia vero.Simile a: tmp = [] for x in seq: if p(x): tmp.append(f(x))
    • 37. Generator Expressions 36 Si può fare restituendo un generatore, ovvero un iterabile “lazy” Il calcolo avviene solo mano a mano che i nuovi elementi sono “richiesti” Sintassi: (f(x) for x in seq if p(x)) Comodo con altre funzioni sum(f(x) for x in seq if p(x)) set(f(x) for x in seq if p(x)) dict((x, i) for (i, x) in enumerate(sorted(seq)))
    • 38. Funzioni 37 def <nome>(<parametri>): <corpo> <corpo> compilato, ma non subito eseguito <parametri>: 0+ variabili locali, inizializzate alla chiamata dagli <args> passati gli 0+ ultimi parameters possono avere "valori di default", <nome>=<expr> (expr è valutata una sola volta, quando def esegue) <parametri> può finire con *<nome> (tupla di arbitrari arg posizionali) e/o **<nome> (dict di arbitrari arg con nome)
    • 39. Esempio:somma di quadrati 38def sumsq(a, b): return a*a+b*bprint sumsq(23, 45) # => 2554O, piú generale:def sumsq(*a): return sum(x*x for x in a)print sumsq(23, 45) # => 2554print sumsq(23, 45, 44, 2) # => 4494Minore livello di astrazione, + lento ma OK:def sumsq(*a): total = 0 for x in a: total += x*x return total
    • 40. “semplice wget” (GvR) 39 import sys import urllib import os def hook(*a): print %s: %s % (fn, a) for url in sys.argv[1:]: fn = os.path.basename(url) print url, "->", fn urllib.urlretrieve(url, fn, hook)
    • 41. Classi 40 class Stack(object): Classe Stack, eredita da def __init__(self, seq): object (come tutto) self._els = list(seq) Costruttore __init__, ha per def pop(self): return self._els.pop() parametro qualcosa di convertibile in lista def push(self, el): return self._els.append(el) Metodo pop delega al pop def __len__(self): della lista return len(self._els) >>> import stack Push “delega” all’append della >>> s = stack.Stack([1, 4, 7, 8]) lista >>> s.pop() 8 __len__, numero di elementi >>> s.push(3) >>> s.pop() 3
    • 42. Con documentazione 41class Stack(object): Implements a stack def __init__(self, seq): Create a new stack with elements from seq self._elements = list(seq) def pop(self): Remove and return the head of the stack return self._elements.pop() def push(self, element): Add el to the head of the stack return self._elements.append(element) def __len__(self): return len(self._elements)
    • 43. class Duration(object): def __init__(self, minutes=0, seconds=0): if minutes < 0 or seconds < 0: raise ValueError("Duration times should be positive") self._duration = minutes * 60 + seconds 42 def minutes(self): return self._duration / 60 def seconds(self): return self._duration % 60 def __str__(self): return %d:%02d % (self.minutes(), self.seconds())d1 = Duration(minutes=3)d2 = Duration(seconds=6)d3 = Duration(minutes=4, seconds=3)print d1.minutes(), d1.seconds() # => 3 0print d1, d2, d3 # => 3:00 0:06 4:03
    • 44. Operatori 43In Python sono disponibili operatori per i tipidefiniti dall’utente (== C++, != Java) Python C++ uguale/diverso __eq__ operator== addizione __add__ operator+ minore __lt__ operator< [] __(g|s)etitem__ operator[] chiamata funz. __call__ operator() hash __hash__ ... conversioni __int__ operator int ... ... ...
    • 45. class Duration(object): ... def __add__(self, other): 44 return Duration(seconds=self._duration + other._duration)class Track(object): def __init__(self, artist, title, duration): self.artist = artist self.title = title self.duration = duration def __str__(self): return %s - %s - %s % (self.artist, self.title, self.duration)
    • 46. class MusicRecord(object): def __init__(self, title, tracks): self.title = title if not tracks: raise ValueError("Empty track list.") self.tracks = tuple(tracks) 45 def is_compilation(self): artists = set(track.artist for track in self.tracks) return len(titles) > 1 def get_duration(self): return sum((track.duration for track in self.tracks), Duration()) def get_artist(self): if self.is_compilation(): return AA. VV. else: return self.tracks[0].title def get_title(self): return self.title
    • 47. lz = Led Zeppelintracks = [ Track(lz, Whole Lotta Love, Duration(5, 34)), Track(lz, What Is and What Should Never Be, 46 Duration(4, 44)), Track(lz, The Lemon Song, Duration(6, 19)), Track(lz, Thank You, Duration(4, 47)), Track(lz, Heartbreaker, Duration(4, 14)), Track(lz, "Living Loving Maid (Shes Just a Woman)", Duration(2, 39)), Track(lz, Ramble On, Duration(4, 23)), Track(lz, Moby Dick, Duration(4, 21)), Track(lz, Bring It On Home, Duration(4, 20))]lz2 = MusicRecord(Led Zeppelin II, tracks)print lz2.get_duration() # => 41:21
    • 48. Properties (I) 47 class A(object): Abbiamo scelto di usare per def __init__(self, foo): Track attributi pubblici self._foo = foo def get_foo(self): Supponiamo di volere print got foo return self._foo aggiungere controlli, per esempio validare gli def set_foo(self, val): print set foo assegnamenti, oppure self._foo = val renderli impossibili... foo = property(get_foo, set_foo) bisognerebbe modificare il a = A(ciao) codice? print a.foo # => got foo property: sintassi di attributi, # => ciao a.foo = bar sotto chiama funzioni # => set foo
    • 49. Properties (II) 48 E se non vogliamo il setter del tutto? Non mettiamolo! class A(object): def __init__(self, foo): self._foo = foo def get_foo(self): print got foo return self._foo foo = property(get_foo) a = A(ciao) print a.foo # => got foo # => ciao a.foo = bar # Traceback (most recent call last): # File "prop_example2.py", line 15, in <module> # a.foo = bar # AttributeError: cant set attribute
    • 50. Properties (III) 49 Snelliamo la sintassi. Possiamo usare un decoratore class A(object): def __init__(self, foo): self._foo = foo @property def foo(self): print got foo return self._foo a = A(ciao) print a.foo # => got foo # => ciao a.foo = bar # Traceback (most recent call last): # File "prop_example2.py", line 15, in <module> # a.foo = bar # AttributeError: cant set attribute
    • 51. Properties (IV) 50 Con Python 2.6, anche con setter: class A(object): def __init__(self, foo): self._foo = foo @property def foo(self): print got foo return self._foo @foo.setter def foo(self, value): print set foo self._foo = value a = A(ciao) a.foo = bar # => set foo
    • 52. class Track(object): def __init__(self, artist, title, duration): self._artist = artist self._title = title self._duration = duration 51 @property def artist(self): return self._artist @property def title(self): return self._title @property def duration(self): return self._duration def __str__(self): return %s - %s - %s % (self.artist, self.title, self.duration)
    • 53. class MusicRecord(object): def __init__(self, title, tracks): self.title = title if not tracks: raise ValueError("Empty track list.") 52 self.tracks = tuple(tracks) self._artists = set(track.artist for track in self.tracks) self._duration = sum((track.duration for track in self.tracks), Duration()) @property def is_compilation(self): return len(self._titles) > 1 @property def duration(self): return self._duration @property def artist(self): if self.is_compilation: return AA. VV. else: return self.tracks[0].title
    • 54. Adulti e vaccinati... 53 Possiamo impedire l’accesso usando le properties Possiamo usare meta-programmazione1 per scrivere meno codice Es... namedtuple, definita nella libreria standard Track = collections.namedtuple( Track, [title, artist, duration]) 1. meta-programmazione: scrittura di programmi che scrivono o modificano altri programmi (o se stessi) come i loro dati
    • 55. Decoratori (I) 54 def log(f): Un decoratore nella sua def _aux(*args, **kargs): generalità è una funzione che print Called %s % f.__name__ return f(*args, **kargs) accetta una funzione come return _aux parametro e ne restituisce @log def double(n): una versione modificata return 2 * n @deco class eg(object): def f(...): ... @log def foo(self): equivale a: print foo def f(...): ... double(10) # => Called double eg().foo() f = deco(f) # => Called foo # => foo
    • 56. Decoratori (II) 55 Esempio da Django (web framework) from django.contrib.auth.decorators import login_required @login_required def my_view(request): ... Un decoratore può anche avere argomenti I decoratori si possono combinare class Bank(object): # ... @with_logger(default_logger) @atomic def transfer(self, from_, to, amount): self.accounts[from_] -= amount # raises NegativeAccountError self.accounts[to] += amount
    • 57. Dinamismo eintrospezione 56 Quando un attributo di un oggetto non viene trovato, se è definito il metodo __getattr__ Se si, viene chiamato con come parametro il nome dell’attributo cercato Esempio: delega [prossima slide] Funzione getattr: prende un attributo per nome f.foo
 
getattr(f,
‘foo’)
    • 58. Stack (con delega) 57 class Stack(object): delegates = dict(pop=pop, push=append) def __init__(self, seq): self._elements = list(seq) def __getattr__(self, value): try: delegate_name = Stack.delegates[value] except KeyError: raise AttributeError else: delegate_method = getattr(self._elements, delegate_name) return delegate_method
    • 59. Convenzioni (PEP8) 58 http://www.python.it/doc/articoli/pep-8.html
    • 60. Importare Moduli 59import nomemodulofrom un.certo.package import nomemodulo poi si usa nomemodulo.foo ci sono abbreviazioni (non necessariamente buone...): accorciare i nomi con la clausola as: import itertools as it poi si usa it.izip from itertools import izip from itertools import *
    • 61. Esempio di Import 60import mathprint math.atan2(1, 3)# emette 0.321750554397print atan2(1, 3)# solleva uneccezione NameErrorfrom math import atan2 inietta atan2 nel namespace corrente comodo in interattivo, ma spesso illeggibile in “veri” programmi: evitare! peggio ancora (evitare COME LA PESTE!): from math import *
    • 62. Definire Moduli 61ogni sorgente Python wot.py è un modulobasta fare import wot deve vivere nella path dimportazione ...che è la lista path nel modulo sys, ogni elemento una stringa che nomina un dir (o zipfile, ...) contenente moduli Python pure importabili: file di bytecode (wot.pyc), automaticamente creati dal compilatore Python quando importi un .py pure importabili: estensioni binarie (wot.pyd), scritte in C (or pyrex, SWIG, ...)
    • 63. Persistenza 62 cPickle: tutti gli oggetti sono facilmente e automaticamente serializzabili su disco Modulo shelve Si usa come un dizionario, offre gratis persistenza su disco per strutture chiave-valore Esigenze maggiori? SQLite integrato con Python Non basta? PostgreSQL Scriptabile in Python Accessibile da Python (+ ORM, SQLAlchemy)
    • 64. Rete 63Modulo socket, offre socket C-like (ma piùsemplici da usare)Moduli asyncore: programmazione asincronasempliceModuli poplib, urllib, smtplib, email, imaplibModuli serverside: TCPServer, TCPForkingServer,TCPThreadingServer, UDP...Twisted (asyncrono, altissima efficienza)Tornado (facebook)
    • 65. Interfacce grafiche 64 Tkinter Multipiattaforma, libreria standard, bruttarello Qt Piattaforma ricchissima, cross-platform, ++ wx Cross-platform, ... [non inneschiamo flames] GTK, Cocoa, WinAPI, + .Net con IronPython, Swing con Jython, FLTK...
    • 66. Calcolo scientifico 65 PIL Manipolazione immagini Numpy+Matplotlib Calcolo numerico, simile a Matlab/Octave Scipy Ulteriori librerie http://www.scipy.org/
    • 67. Web 66cgi (sconsigliato)/fastcgiWSGI: modulo di medio livello per interfacciarsicon i serverDjango: framework completo, molto usatoNevow: framework completo basato su TwistedZope2/3: “mega framework”Google App Engine (+web.py ev. Django)web.py: modulo minimalista, facile comprensione
    • 68. Q&AHelp System Ancora su Classi e Istanze 67 Generatori &Attributi di Classe Generatori Infiniti Scope With Statement Duck Typing
    • 69. Help system 68 >>> help(os.getcwd)La funzione help() da aiuto su getcwd(...) getcwd() -> pathuna funzione/classe/modulo Return a string representing the current working direcetc. >>> help(sys) Help on built-in module sys:Se chiamata sull’istanza di NAMEuna classe (quindi anche un sysnumero o una stringa) da FILEinformazioni sulla classe (built-in)Di fatto va a leggere le MODULE DOCS http://www.python.org/doc/current/lib/module-sys.h‘docstring’ (vediamo poi...) DESCRIPTION This module provides access to some objects used orConsideriamo anche pydoc interpreter and to functions that interact strongly with
    • 70. Help system 68>>> help(os.getcwd)getcwd(...) getcwd() -> path Return a string representing the current working directory.>>> help(sys)Help on built-in module sys:NAME sysFILE (built-in)MODULE DOCS http://www.python.org/doc/current/lib/module-sys.htmlDESCRIPTION This module provides access to some objects used or maintained by the interpreter and to functions that interact strongly with the interpreter.
    • 71. >>> help(sys.stdout)Help on file object:class file(object) | file(name[, mode[, buffering]]) -> file object | | Open a file. The mode can be r, w or a for reading (default), | writing or appending. The file will be created if it doesnt exist 69 | when opened for writing or appending; it will be truncated when | opened for writing. Add a b to the mode for binary files. ...bash> pydoc os.path.joinHelp on function join in os.path:os.path.join = join(a, *p) Join two or more pathname components, inserting / as neededbash> pydoc -p 8080pydoc server ready at http://localhost:8080/% python>>> help()Welcome to Python 2.5! This is the online help utility.help> To Q&A
    • 72. >>> help(sys.stdout)Help on file object:class file(object) | file(name[, mode[, buffering]]) -> file object | | Open a file. The mode can be r, w or a for reading (default), | writing or appending. The file will be created if it doesnt exist 69 | when opened for writing or appending; it will be truncated when | opened for writing. Add a b to the mode for binary files. ...bash> pydoc os.path.joinHelp on function join in os.path:os.path.join = join(a, *p) Join two or more pathname components, inserting / as neededbash> pydoc -p 8080pydoc server ready at http://localhost:8080/% python>>> help()Welcome to Python 2.5! This is the online help utility.help> To Q&A
    • 73. Attributidi istanza e di classe 70 class A(object): Fino ad ora abbiamo visto cattr = [] def __init__(self): come aggiungere attributi alle self.iattr = [] istanze delle classi (banale) def add(self, obj): self.cattr.append(obj) Sappiamo che le funzioni, in self.iattr.append(obj) un certo senso sono attributi a1 = A() degli “oggetti classe” a2 = A() a1.add(x) print a1.cattr, a1.iattr Se definiamo un attributo nel # => [x], [x] corpo di una classe, è un print a2.cattr, a2.iattr # => [x], [] attributo di classe a2.add(y) print a1.cattr, a1.iattr # => [x, y], [x] print a2.cattr, a2.iattr # => [x, y], [y]
    • 74. Metodi di classe 71 I metodi di classe si class A(object): @classmethod definiscono con il decoratore def say(cls, m): classmethod print cls.__name__, m Hanno come primo A.say(hello) # => A hello argomento l’oggetto classe a = A() Accedono ad attributi di a.say(hello) # => A hello classe (ma non d’istanza) Convenzionalmente, chiamiamo il primo parametro cls e non self To Q&A
    • 75. With statement 72 with file(foo.txt) as f: for line in f: print line.strip() with gestisce un “contesto”, quando si esce dalblocco with (con eccezione o meno), vienegestita la chiusura di fileSimile agli idiomi RAII (resource allocation isinitialization) di C++, ma molto più facile dagestire
    • 76. Vecchio esempio... 73 import sys filename = sys.argv[1] indx = {} with open(filename) as f: for n, line in enumerate(f): for word in line.split(): indx.setdefault(word, []).append(n) # mostriamola in indice alfabetico for word in sorted(indx): print "%s:" % word, for n in indx[word]: print n, print To Q&A
    • 77. Generatori 74 def couples(l):funzioni con yield invece di i = 0return length = len(l) while i < length-1:ogni chiamata costruisce e yield l[i], l[i+1]torna un iteratore (oggetto i += 1con metodo next, adatto a lst = [1, 2, 3, 4, 5, 6]essere iterato in un ciclo for) for pairs in couples(lst):la fine della funzione solleva print pairsStopIteration (1, 2) (2, 3) (3, 4) (4, 5) (5, 6)
    • 78. Generatori Infiniti 75 def fibonacci(): i = j = 1 while True: r, i, j = i, j, i + j yield r for rabbits in fibonacci(): if rabbits > 100: break else: print rabbits, 1 1 2 3 5 8 13 21 34 55 89 To Q&A
    • 79. Classi 76class <nome>(<basi>): <corpo> <corpo> è di solito una serie di istruzioni def e assegnazioni; i nomi definiti o assegnati divengono attributi del nuovo oggetto classe <nome> (le funzioni divengono "metodi") gli attributi di una qualsiasi base sono anche attributi della nuova classe, se non "overridden" (assegnati o definiti nel corpo) Iniziare con singolo _ indica essere privati
    • 80. Istanziare una Classe 77class eg(object): cla = [] # attrib. di classe def __init__(self): # inizializzatore self.ins = {} # attrib. distanza def meth1(self, x): # un metodo self.cla.append(x) def meth2(self, y, z): # altro metodo self.ins[y] = zes1 = eg()es2 = eg()
    • 81. Classi e Istanze 78print es1.cla, es2.cla, es1.ins, es2.ins[] [] {} {}es1.meth1(1); es1.meth2(2, 3)es2.meth1(4); es2.meth2(5, 6)print es1.cla, es2.cla, es1.ins, es2.ins[1, 4] [1, 4] {2: 3} {5: 6}print es1.cla is es2.claTrueprint es1.ins is es2.insFalse
    • 82. Risoluzione degli Attributi 79inst.method(arg1, arg2)type(inst).method(inst, arg1, arg2)inst.nome [[che sia poi chiamato o meno!]] (i "descrittori" possono alterarlo...) prova inst.__dict__[nome] prova type(inst).__dict__[nome] prova ciascuna delle type(inst).__bases__ prova type(inst).__getattr__(inst, nome) se tutto fallisce, raise AttributeError To Q&A
    • 83. Scope delle variabili 80 I parametri di una funzione e ogni variabile che viene legata (con assegnamento o statement come def o class) nel corpo di una funzione costituisce il namespace della funzione (local scope) Lo scope di queste variabili è tutto il corpo della funzione (ma usarle prima che siano state legate è un errore) Le variabili non locali sono dette globali, il loro scope è il modulo intero Normalmente non ci sono motivi per usarle To Q&A
    • 84. Scope delle variabili 80 I parametri di una funzione e ogni variabile che viene legata (con assegnamento o statement come def o class) nel corpo di una funzione costituisce il namespace None funzione (local della a= scope) if s.startswith(t): a = s[:4] Lo scope di queste variabili è tutto il corpo della else: funzione (ma usarle prima tche siano state legate a= è un errore) print a Le variabili non locali sono dette globali, il loro SBAGLIATO scope è il modulo intero Normalmente non ci sono motivi per usarle To Q&A
    • 85. Scope delle variabili 80 I parametri di una funzione e ogni variabile che viene legata (con assegnamento o statement come def o class) nel corpo di una funzione costituisce il namespace della funzione (local scope) if s.startswith(t): a = s[:4] Lo scope di queste variabili è tutto il corpo della else: funzione (ma usarle prima tche siano state legate a= è un errore) print a Le variabili non locali sono dette globali, il loro GIUSTO scope è il modulo intero Normalmente non ci sono motivi per usarle To Q&A
    • 86. Pensiamo a Java/C++... 81 Nei linguaggi con un type-system derivato da C+ + chiediamo che i parametri di una certa funzione abbiano un dato tipo (o siano di un sottotipo) Questo è poco flessibile: programmare per un interfaccia Interfacce di Java (vero polimorfismo din.) Templates di C++ (polimorfismo statico) Sono soluzioni con problemi
    • 87. Libri, ricerca per titolo 82Chiamare su una lista che class Book(object): def __init__(self, title, author):contiene un “non libro” self.title = title self.author = authorlancia eccezione def find_by_title(seq, title):Eppure non gestiamo for item in seq: if type(item) == Book: # horriblenemmeno sottoclassi if item.title == title: return itemPeggior codice possibile, else: raise TypeErrorinoltre stiamo risolvendo def find_by_author(seq, author):un non-problema for item in seq: if type(item) == Book: # horrible if item.author == author: return item else: raise TypeError
    • 88. Libri, ricerca per titolo 82Chiamare su una lista checontiene un “non libro”lancia eccezioneEppure non gestiamonemmeno sottoclassiPeggior codice possibile,inoltre stiamo risolvendoun non-problema
    • 89. Libri, ricerca per titolo 83Ora gestiamo sottoclassi class Book(object): def __init__(self, title, author): self.title = titleEppure noi non usiamo mai self.author = authoril fatto che la cosa sia un def find_by_title(seq, title):libro for item in seq: if isinstance(item, Book): # bad if item.title == title: Solo che ha un titolo return item else: Solo che ha un autore raise TypeErrorCosa succede se abbiamo def find_by_author(seq, author): for item in seq:una classe Song? if isinstance(item, Book): # bad if item.author == author: return item else: raise TypeError
    • 90. Libri, ricerca per titolo 83Ora gestiamo sottoclassiEppure noi non usiamo maiil fatto che la cosa sia un def find_by_title(seq, title):libro for item in seq: if isinstance(item, Book): # bad if item.title == title: Solo che ha un titolo return item else: Solo che ha un autore raise TypeErrorCosa succede se abbiamo def find_by_author(seq, author): for item in seq:una classe Song? if isinstance(item, Book): # bad if item.author == author: return item else: raise TypeError
    • 91. Libri, ricerca per titolo 83Ora gestiamo sottoclassi class Song(object): def __init__(self, title, author): self.title = titleEppure noi non usiamo mai self.author = authoril fatto che la cosa sia un def find_by_title(seq, title):libro for item in seq: if isinstance(item, Book): # bad if item.title == title: Solo che ha un titolo return item else: Solo che ha un autore raise TypeErrorCosa succede se abbiamo def find_by_author(seq, author): for item in seq:una classe Song? if isinstance(item, Book): # bad if item.author == author: return item else: raise TypeError
    • 92. Libri e canzoni 84 La cosa più semplice è la miglioreclass Book(object): I programmatori tendono a non def __init__(self, t, a): self.title = t scrivere codice a caso self.author = a Abbiamo sempre eccezionidef find_by_title(seq, title): for item in seq: lanciate if item.title == title: return item I test servono apposta perdef find_by_author(seq, author): prendere ‘sta roba for item in seq: if item.author == author: return item
    • 93. E se avessimo film? 85 I film hanno sempre un titolo, ma non hanno un autore, bensì un regista find_by_title dovrebbe funzionare, find_by_author, no Interfaccia per Book e Song. E per Movie? Design Pattern o duplicazione di codice Ruota quadrata strade per ruote quadrate Con il duck typing non dobbiamo cambiare nulla
    • 94. def find_by(seq, **kwargs): for obj in seq: To Q&A for key, val in kwargs.iteritems(): try: if getattr(obj, key) != val: break except KeyError: break else: return obj raise NotFoundprint find_by(books, title=Python in a Nutshell)print find_by(books, author=M. Beri)print find_by(books, title=Python in a Nutshell, author=A. Martelli)try: print find_by(books, title=Python in a Nutshell, author=M.Beri) print find_by(books, title=Python in a Nutshell, pages=123)except NotFound: pass

    ×