A simple introduction to the Python programming language. In Italian. OLD: superseeded by Pycrashcourse 3.1.
Originally part 1 of a 4 lectures seminar for the Networking class of the Computer Science course at the University of Parma
2. Parlando del
futuro...
We will perhaps eventually be
writing only small modules that are
identified by name as they are
used to build larger ones, so that
devices like indentation, rather than
delimiters, might become feasible
for expressing local structure in the
source language.
Donald E. Knuth, Structured
Programming with go to
Statements, 1974
4. Introduzione
Python è concepito da Guido van Rossum alla fine
degli anni ‘80 per Amoeba
5. Introduzione
Python è concepito da Guido van Rossum alla fine
degli anni ‘80 per Amoeba
Pubblico 1991, stabile 1994.
6. Introduzione
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.
7. Introduzione
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
8. Introduzione
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 Nevow (basato su
Twisted).
9. Piattaforma Python
“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
Implementazione in C, Java e.NET
10. Comunità Python
Una forte comunitá open-source
Molti utenti (individui e compagnie) in tutti i campi
Python Software Foundation (in Italia, Python Italia)
Gruppi d’interesse per argomenti specifici
Siti web, newsgroup, mailing list, ...
Corsi, laboratori, tutorial, conferenze (Pycon Italia, tre
edizioni, più grande conferenza open italiana)
Molti (specialmente in inglese...) in linea, su carta, o
entrambi
11. Indice TIOBE Marzo 2009
Sesto linguaggio più diffuso
secondo l’indice TIOBE e in Linguaggio Pos. Diff.
crescita continua 1 Java -1.7%
Utilizzato presso Google 2 C +1%
(linguaggio principale), 3 C++ +1%
NASA, Industrial Lights and
Magic, Frequentis (sicurezza 4 PHP -0.4%
aerea), ... 5 VB -3.3%
6 Python +0.4%
7 C# -0.2%
12. Python da 3000 metri (1)
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
13. Python da 3000 metri
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
Possiamo fare, in definitiva, tutto
14. Versioni
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.0 é una major release non pensata
ancora per essere usata in produzione. É il
Python di domani, ma oggi é oggi
15. Dettagli implementativi
Tipicamente Python viene % cat hello.py
#!/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
16. Interprete interattivo
L’interprete interattivo ufficiale ha
>>> import os
come prompt >>> >>> print 'foo'
foo
Scriviamo comandi (statements) >>> os.getcwd()
'/Users/enric/uni/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'
17. Letterali
>>> 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
18. a = 16
print a
a = 7.6
Variabili
print a
print a * 2
a = 'ciao'
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
19. Ancora letterali
Tuple: >>> t = 1, 2, 'a'
>>> a, b, c = t
Sequenza di oggetti non >>> print b
2
modificabile >>> print t
(1, 2, 'a')
Facile da pack/unpack >>> str(1, 2, 3)
Traceback (most recent call last):
Precedenza File "<stdin>", line 1, in <module>
TypeError: str() takes at most 1
argument (3 given)
Dizionario (array associativo): >>> str((1, 2, 3))
'(1, 2, 3)'
Coppie chiave/valore >>> d = {'foo' : 1, 'bar': 8}
>>> d
Inserimento/Accesso O(1) {'foo': 1, 'bar': 8}
Chiavi “immutabili”
20. Help system
>>> help(os.getcwd)
La funzione help() da aiuto su getcwd(...)
getcwd() -> path
una funzione/classe/modulo
Return a string representing the current working direc
etc. >>> help(sys)
Help on built-in module sys:
Se chiamata sull’istanza di
NAME
una classe (quindi anche un sys
numero o una stringa) da FILE
informazioni 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 or
Consideriamo anche pydoc interpreter and to functions that interact strongly with
21. Help system
>>> help(os.getcwd)
getcwd(...)
getcwd() -> path
Return a string representing the current working directory.
>>> help(sys)
Help on built-in module sys:
NAME
sys
FILE
(built-in)
MODULE DOCS
http://www.python.org/doc/current/lib/module-sys.html
DESCRIPTION
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.
22. >>> 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 doesn't exist
| 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.join
Help on function join in os.path:
os.path.join = join(a, *p)
Join two or more pathname components, inserting '/' as needed
bash> pydoc -p 8080
pydoc server ready at http://localhost:8080/
% python
>>> help()
Welcome to Python 2.5! This is the online help utility.
help>
23. >>> 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 doesn't exist
| 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.join
Help on function join in os.path:
os.path.join = join(a, *p)
Join two or more pathname components, inserting '/' as needed
bash> pydoc -p 8080
pydoc server ready at http://localhost:8080/
% python
>>> help()
Welcome to Python 2.5! This is the online help utility.
help>
24. Controllo di flusso
Condizionale: Su if c’é poco da dire; while
if cond: si 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:
statement
Disponibili break/continue
else di for/while esegue su
while cond:
statement terminazione naturale (no exc/
cont/break/return)
25. Liste
>>> a = [1, 2, 'a', 'ciao', 4]
La lista é in realtà un array: >>> 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
26. Liste (altri metodi)
>>> a
Presenti anche: [1, 2, 'a', 'ciao', 4, 3, 1, 2]
>>> a[1:4]
[2, 'a', 'ciao']
insert(i, o): inserisci o in >>> a[1:8:2]
posizione i [2, 'ciao', 3, 2]
>>> a[::-1]
[2, 1, 3, 4, 'ciao', 'a', 2, 1]
remove(v): togli la prima >>> a
occorrenza di v [1, 2, 'a', 'ciao', 4, 3, 1, 2]
count(v): ...
>>> for el in a:
index(v): ... ... print el,
...
sort(): ... 1 2 a ciao 4 3 1 2
Le liste sono mutabili
27. Liste (altri metodi)
>>> a
Presenti anche: [1, 2, 'a', 'ciao', 4, 3, 1, 2]
>>> a[1:4]
[2, 'a', 'ciao']
insert(i, o): inserisci o in >>> a[1:8:2]
posizione i [2, 'ciao', 3, 2]
>>> a[::-1]
[2, 1, 3, 4, 'ciao', 'a', 2, 1]
remove(v): togli la prima >>> a
occorrenza di v [1, 2, 'a', 'ciao', 4, 3, 1, 2]
count(v): ...
>>> for el in a:
index(v): ... ... print el,
...
sort(): ... 1 2 a ciao 4 3 1 2
Le liste sono mutabili Virgola finale non va a capo
28. Tuple
>>> 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 12a
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 attribute 'append'
Per il resto funziona tutto >>> l.append(5)
>>> l
come previsto [1, 2, 'x', 5]
30. Operazioni se sequenze
>>> s = 'ciao'
Stringhe, tuple e liste sono >>> m = 'mondo'
>>> min(s) # <= 'a'
sequenze >>> max(m) # <= 'o'
>>> l = [1, 2, 3]
Tutte le sequenze >>> sum(l) # <= 6
>>> s + m # <= 'ciaomondo'
supportano alcune >>> s + l
Traceback (most recent call last):
operazioni File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'list' objects
min/max/sum >>> list(s) + l
['c', 'i', 'a', 'o', 1, 2, 3]
+ : concatenazione >>> '=' * 10
'=========='
>>> [1, ] * 10
S * n/ n * S: ripetizione [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
>>> ‘a’ in s
el in S: appartenenza True
>>> ‘pippo’ in l
False
31. Attenzione!
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)
>>> l = ['usr', 'local', 'lib']
>>> '/'.join(l)
'usr/local/lib'
>>> ' => '.join(l)
'usr => local => lib'
Per concatenare pezzi di path, usare os.path.join e i metodi
presenti in os.path
32. Statement For
for ch in 'ciao mondo':
For é il modo più comune di 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)
33. Statement For
for ch in 'ciao mondo':
For é il modo più comune di 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)
34. Iteratori e cicli for
for i in c: <body>
[p for p in nums if isprime(p)]
_t = iter(c)
while True:
try: i = _t.next()
except StopIteration: break
<body>
anche: (<expr>for i in c <opt.clauses>)
[<expr> for i in c <opt.clauses>]
("genexp" e "list comprehension")
35. Dizionari
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...)
36. Dizionari (altri metodi)
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)
aD
37. Dizionari (Iterazione)
% python dicts_example.py
d = {'foo' : (1, 2, 3), foo
'bar' : (2, 3, 4)} bar
foo
for k in d: bar
print k (1, 2, 3)
(2, 3, 4)
for k in d.iterkeys(): foo (1, 2, 3)
print k bar (2, 3, 4)
foo (1, 2, 3)
for v in d.itervalues(): bar (2, 3, 4)
print v
for k, v in d.iteritems(): # iteritems restituisce un iteratore alle coppie
print k, v
for k, v in d.items(): # items restituisce una *lista*
print k, v
38. Dimensione di oggetti
iterabili
Il builtin (funzione) len dice il numero di elementi
di ogni oggetto iterabile
Se dispongono di un metodo __len__ chiama
quello. Per esempio per liste, tuple, dizionari,
stringhe, insiemi (set)
Funziona anche su un generatore, ma in questo
caso potrebbe doverlo scorrere
39. Format
Le stringhe hanno un operatore % che permette di fare “format
string” simili alla printf del C -- doc per maggiori informazioni --
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)
40. I/O elementare
due funzioni built-in per l'input elementare
input(prompt): immette qualsiasi espressione -- ne torna il valore
raw_input(prompt): torna una stringa, rimuove il n a fine stringa
una istruzione per l'output elementare
print <0+ espressioni separate da virgole>
separa i risultati con uno spazio
n alla fine (ma non se finite con virgola)
print di suo non fa formattazioni speciali
print >> writable, <0+ espressioni separate da virgole>
41. SPERIMENTATE!
Non é possibile imparare un linguaggio con una
corso frontale.
I linguaggi si imparano programmando, provando
codice etc.
In Python trovate tutto quello che vi serve o
direttamente nella libreria standard o in qualche
modulo esterno: dateci qualche occhiata
Leggete la documentazione. Studiate il codice
altrui. É estremamente leggibile e didattico
Diffidate dal codice che ha un brutto aspetto
42. “semplice wget” (GvR)
import sys, urllib, 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)
43. Eccezioni
Errori (e “anomalie” che non sono errori)
“sollevano eccezioni” (istanze di Exception o
qualsiasi sottotipo di Exception -- ma anche no)
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
L'istruzione try/except può catturare eccezioni
(anche: try/finally, e l'elegante with per
implementare “RAII”)
44. LBYL vs. EAFP
LBYL: Look before you leap
EAFP: Easier to ask forgiveness
than permission try:
emp = employees[user_name]
except KeyError:
Normalmente EAFP é la report_error(...)
strategia migliore in Python if user_name in emp:
emp = employees[user_name]
Eccezioni relativamente poco else:
costose report_error(...)
Atomicità, ...
45. Vari tipi di try
try:
# codice che potrebbe lanciare eccezione
except IndexError, exc:
# un tipo di errore
# opzionalmente si mette ‘, nome’ per avere
# l’oggetto eccezione da gestire
except AnotherException:
# gestione di un altro errore
except:
# gestione di ogni eccezione
# tipicamente *NON* e' una buona pratica
# a meno di non rilanciare
raise # raise vuoto rilancia l'eccezione corrente
finally:
# questo codice e' eseguito *sempre*
# codice di pulizia sia con errore che senza
46. With statement
from __future__ import with_statement
with file('foo.txt') as f:
for line in f:
print line.strip()
47. Funzioni
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)
48. Esempio: somma di
quadrati
def sumsq(a, b): return a*a+b*b
print sumsq(23, 45)
O, piú generale:
def sumsq(*a):
return sum(x*x for x in a)
Minore livello di astrazione, + lento ma OK:
def sumsq(*a):
total = 0
for x in a: total += x*x
return total
49. Scope delle variabili
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
50. Scope delle variabili
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
51. Scope delle variabili
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
52. Generatori
def couples(l):
i = 0 funzioni con yield invece di
while i < len(l)-1: return
yield l[i], l[i+1]
i += 1 ogni chiamata costruisce e
torna un iteratore (oggetto
lst = [1, 2, 3, 4, 5, 6] con metodo next, adatto a
for pairs in couples(lst):
print pairs
essere iterato in un ciclo for)
la fine della funzione solleva
...
(1, 2) StopIteration
(2, 3)
(3, 4)
(4, 5)
(5, 6)
53. Generatori Infiniti
def fibonacci():
i = j = 1
while True:
r, i, j = i, j, i + j
yield r
for rabbits in fibonacci():
print rabbits,
if rabbits > 100: break
1 1 2 3 5 8 13 21 34 55 89 144
54. Classi
class <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
55. Istanziare una Classe
class eg(object):
cla = [] # attrib. di classe
def __init__(self): # inizializzatore
self.ins = {} # attrib. d'istanza
def meth1(self, x): # un metodo
self.cla.append(x)
def meth2(self, y, z): # altro metodo
self.ins[y] = z
es1 = eg()
es2 = eg()
57. Risoluzione degli Attributi
inst.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
58. Sottoclassi
class sub(eg):
def meth2(self, x, y=1): # override
eg.meth2(self, x, y) # super-call
# or: super(sub, self).meth2(x, y)
class repeater(list):
def append(self, x):
for i in 1, 2:
list.append(self, x)
class data_overrider(sub):
cla = repeater()
59. Proprietà
class blah(object):
def getter(self):
return ...
def setter(self, value): ...
name = property(getter, setter)
inst = blah()
Ora...:
print inst.name # come inst.getter()
inst.name = 23 # come inst.setter(23)
60. Overload di Operatori
“metodi speciali”: nomi che iniziano e
finiscono con due _ (pron “dunder”!):
__new__ __init__ __del__ # init/final.
__repr__ __str__ __int__ # conversioni
__lt__ __gt__ __eq__ ... # paragoni
__add__ __sub__ __mul__ ... # aritmetica
__call__ __hash__ __nonzero_ ...
__getattr__ __setattr__ __delattr__
__getitem__ __setitem__ __delitem__
__len__ __iter__ __contains__
Python chiama i metodi speciali del tipo
quando tu operi sulle istanze del tipo
61. Overload di Operatori
“metodi speciali”: nomi che iniziano e
finiscono con due _ (pron “dunder”!):
__new__ __init__ __del__ # init/final.
__repr__ __str__ __int__ # conversioni
__lt__ __gt__ __eq__ ... # paragoni
__add__ __sub__ __mul__ ... # aritmetica
__call__ __hash__ __nonzero_ ...
__getattr__ __setattr__ __delattr__
N.B. : In Python
__getitem__ __setitem__ __delitem__
l’overload dei metodi
__len__ __iter__ __contains__
non esiste e non
Python chiama i metodi speciali del tipo
serve!
quando tu operi sulle istanze del tipo
63. Decoratori
def log(f):
Un decoratore nella sua def _aux(*args, **kargs):
print 'Called %s' % f.__name__
generalità é una funzione che return f(*args, **kargs)
return _aux
accetta una funzione come
parametro e ne restituisce @log
def double(n):
una versione modificata return 2 * n
É come: class eg(object):
@log
def f(...): def foo(self):
print 'foo'
...
double(10)
f = deco(f) eg().foo()
64. Metodi static/class
Python offre due decoratori staticmethod e
classmethod per metodi “statici” e metodi “di
classe”
Convenzionalmente il primo parametro dei
metodi di classe si chiama cls e non self
I metodi “statici” non hanno “primo argomento”
Cercare nell’help maggiori informazioni, se
interessa. Si vive anche senza.
65. Funzioni Builtin
non chiamare metodi speciali direttamente:
operatori e funzioni built-in lo fanno "bene"
ad es.: abs(x), NON x.__abs__()
ci sono molti built-in interessanti, come:
abs any all chr cmp compile dir enumerate
eval getattr hasattr hex id intern
isinstance iter len max min oct open ord pow
range repr reversed round setattr sorted sum
unichr xrange zip
molti altri tipi e funzioni utili e interessanti sono
nei moduli della libreria standard!
66. Esempio
# costruiamo mappa parola->[numeri riga]
indx = {}
try:
f = open(filename)
for n, line in enumerate(f):
for word in line.split():
indx.setdefault(word, []).append(n)
finally:
f.close()
# mostriamola in indice alfabetico
for word in sorted(indx):
print "%s:" % word,
for n in indx[word]: print n,
print
67. Altre possibilità
# le 7 parole piú frequenti nel testo:
import heapq
for w in heapq.nlargest(7, indx, key=indx.get):
print w
# linee che contengono N parole date:
def enwhack(*parole):
parole = list(parole)
r = set(indx[parole.pop()])
for p in parole:
r &= set(indx[p])
return sorted(r)
68. Importare Moduli
import nomemodulo
from un.certo.package import nomemodulo
poi si usa nomemodulo.blah
ci sono abbreviazioni (non nec. buone...):
accorciare i nomi con la clausola as:
import nometroppolungo as z
poi si usa z.blah
from nometroppolungo import blah
from nometroppolungo import *
69. Esempio di Import
import math
print math.atan2(1, 3)
# emette 0.321750554397
print atan2(1, 3)
# solleva un'eccezione NameError
from 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 *
70. Definire Moduli
ogni sorgente Python wot.py é un modulo
basta fare import wot
deve vivere nella path d'importazione
...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, ...)
71. Cosa è un Modulo
Un modulo é un semplice oggetto con attributi;
gli attributi sono i nomi “toplevel” connessi da
assegnazioni, o istruzioni assegnanti: class, def,
import, from
Gli attributi di modulo sono detti anche “variabili
globali” del modulo
Possono venir connessi o sconnessi anche “da
fuori” (prassi discutibile, ma comoda in
particolare per i test con la design pattern Mock
[ma Dependency Injection é meglio])
72. Tempi di Apprendimento
Tempi necessari a un programmatore esperto per
imparare 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