Linguaggio
Python
Speaker: Alessandro Giuliani
Infelligent Agents and Soft-Computing Group
Dept. of Electrical and Electronic Engineering
University of Cagliari, Italy
email: [email protected]
Introduzione
Introduzione
Sviluppato da Guido Van Rossum (1991)
Paradigmi:
Object Oriented
Programming
Scripting
(Perl, Tcl, …)
(C++, Java, …)
Python
Functional Programming
(CommonLisp, Haskell, …)
Introduzione
Popolarità
Introduzione
Popolarità
Introduzione
Popolarità
Introduzione
Chi Usa Python?
NASA per lo sviluppo di sistemi di controllo;
Yahoo! in alcuni servizi di internet;
Google
Youtube
RedHat
…
Caratteristiche Generali
Semplicità e facilità di lettura
Esempio: stampare i valori interi da 0 a 9:
Python:
C++:
for i in range(10):
print i
int i
for (i=0; i<10; i++){
printf("%d", i);}
Caratteristiche Generali
Alcune statistiche dicono che un programma scritto in
Python è tipicamente più corto e breve di 3-5 volte rispetto
ad un programma scritto in Java ed addirittura di 5-10 volte
rispetto ad un programma scritto in C++.
Caratteristiche Generali
Linguaggio non compilato!
Python è in genere considerato un linguaggio interpretato,
ma in realtà il codice sorgente non viene convertito
direttamente in linguaggio macchina, ma passa prima da una
fase di pre-compilazione in bytecode.
Lo stesso bytecode viene quasi sempre riutilizzato dopo la
prima esecuzione del programma, evitando così di dover ogni
volta interpretare il sorgente ed incrementando di
conseguenza le prestazioni.
Caratteristiche Generali: Duck Typing
“Quando io vedo un uccello che cammina come un'anatra,
nuota come un'anatra e starnazza come un'anatra, io chiamo
quell'uccello anatra” (J.W.Riley)
Se una variabile la usiamo come numero intero, le associamo
numeri interi, allora quella variabile denoterà un numero
intero!
Caratteristiche Generali: Duck Typing
Linguaggio dinamicamente tipizzato!
I tipi dati esistono e sono necessari ma non è necessario
dichiararli esplicitamente.
Variabili → puntatori ad oggetto (reference), sono gli oggetti
ad essere dotati di tipo.
Una variabile può cambiare la sua natura durante
l'esecuzione del codice
a = 10
…
a = ['a', 'b', 'c']
implicitamente a è di tipo intero
a diventa di tipo “lista”
Caratteristiche Generali: Sintassi
No terminatori di riga obbligatori
Blocchi di codice specificati con indentazione
Esempio:
def fattoriale(x):
if x == 0:
return 1
return x * fattoriale(x-1)
Caratteristiche Generali: Sintassi
Caratteri principali
: → istruzioni con blocchi indentati
# → commenti (riga singola)
””” → commenti (su più righe)
= → assegnazione
== → test di uguaglianza
”””Questo è un commento
su più righe”””
def fattoriale(x):
if x == 0:
return 1
return x * fattoriale(x-1) #commento singolo
Caratteristiche Generali: Moduli
File che contengono definizioni e istruzioni Python.
Il nome del file è il nome del modulo con il suffisso .py
aggiunto.
Il nome del modulo è disponibile (sotto forma di stringa)
come valore della variabile globale __name__.
I moduli possono importare altri moduli o parti di esso.
import nomeModulo
from nomeModulo import nomeFunzione
Caratteristiche Generali: Tipi di dato
Semplici
int, long, float, bool, complex
Sequenze
Mutabili → consentite modifiche locali dell'oggetto
liste, dizionari, set, file
Immutabili → una volta create non si possono modificare
stringhe, tuple
Caratteristiche Generali: Tipi di dato
Liste
Serie ordinata di valori, ognuno identificato da un indice
Gli elementi possono essere di tipo diverso
Esempi:
[10, 20, 30, 40]
["Pippo", "Pluto", "Paperino"]
["ciao", 2.0, 5, [10, 20]]
Caratteristiche Generali: Tipi di dato
Tuple
Simili alle liste, l'unica differenza è che sono oggetti
immutabili
Esempi:
(10, 20, 30, 40)
("Pippo", "Pluto", "Paperino")
("ciao", 2.0, 5, [10, 20])
Caratteristiche Generali: Tipi di dato
Set
Collezione non ordinata che non contiene elementi duplicati al
suo interno.
Esempio:
a = [1, 2, 3, 3]
set(a) → Output: {1, 2, 3}
Caratteristiche Generali: Tipi di dato
Dizionari
Tipi di dato in cui si può usare qualsiasi tipo di dato
immutabile come indice.
Gli elementi appaiono in una sequenza separata da virgole.
Ogni voce contiene un indice (chiave) univoco ed il
corrispondente valore separati da due punti.
Esempio:
{"a" : 10, "b" : 20, "c" : 30)
Strutture di Controllo e Iterazioni
Controllo condizionale: if: … else: …
if Condizione: #Se Condizione è vera esegui le istruzioni
indentate …
else: #altrimenti, se Condizione è falsa esegui le istruzioni
indentate …
Esempio:
def fattoriale(x):
if x == 0:
return 1
else:
return x * fattoriale(x-1)
Strutture di Controllo e Iterazioni
Cicli while
Se è richiesta la ripetizione iterativa di un certo gruppo di
istruzioni (tipo Ripeti-Finché) si adotta costrutto while:
while (Condizione): #Finché Condizione è vera esegui le
istruzioni indentate: …
Esempio:
def ContoAllaRovescia(n):
while n > 0:
print n
n = n-1
print "Partenza!"
Strutture di Controllo e Iterazioni
Cicli for
Equivalente al while, itera su strutture (es.liste e dizionari), e
qualunque variabile indicizzata.
L'iterazione è «definita», ovvero termina non appena gli
elementi del dato sono stati esaminati tutti.
for <iterazione su un dato iterabile>: #esegui le istruzioni
indentate: …
Esempio:
#iterazione su una lista con for
for x in lista:
print x
Funzione Range
range → genera liste contenenti progressioni aritmetiche.
Sintassi:
range(n) → genera una sequenza di n numeri interi, partendo dal
valore 0.
range(10) → [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range(start, stop) → genera una sequenza di numeri interi
progressivi, partendo dal valore start, fino al valore stop (non incluso
nella sequenza).
range(1, 4) → [1, 2, 3]
range(start, stop, step) → genera una sequenza di numeri
interi progressivi, partendo dal valore start, fino al valore stop, non
incluso nella sequenza, con passo pari a step.
range(1, 8, 2) → [1, 3, 5, 7]
Funzioni
La sintassi per definire una funzione è molto semplice:
def nome_funzione(<lista parametri separati da virgola>):
<blocco istruzioni>
return <risultato>
def fattoriale(x):
if x == 0:
return 1
return x * fattoriale(x-1)
Funzioni: Scope
Variabili locali → utilizzabili solo dalle funzioni.
Variabili globali → appartenenti al namespace del modulo
(utilizzabili al di fuori della funzione).
Meccanismo di ricerca del nome della variabile
VARIABILE
VARIABILE
NAMESPACE
NAMESPACE
LOCALE
LOCALE
NAMESPACE
NAMESPACE
GLOBALE
GLOBALE
FUNZIONI
FUNZIONI
BUILT-IN
BUILT-IN
Questo meccanismo permette di utilizzare il valore delle
variabili globali, ma di non poterle mai modificare, in quanto un
nuovo assegnamento alla variabile provoca la creazione dello
stesso nome in un namespace nuovo.
Funzioni: Scope
Esempio:
def func():
a = 20
a = 10
func()
print a
Output:
10
Funzioni: Passaggio di Parametri
Il comportamento è paragonabile al passaggio per riferimento
Variabili → etichette applicate agli oggetti
Esempio
def func(x,y):
x.append(30)
y += 1
a = [10, 20]
b = 1
func(a,b)
print a
print b
Funzioni: Passaggio di Parametri
Output
[10, 20, 30]
→ la variabile a è stata modificata
1
→ la variabile b non è stata modificata!
Perché diversi comportamenti?
La variabile a è una lista → mutabile!
La variabile b è un intero → immutabile!
Funzioni: Parametri Opzionali
Parametri che assumono un valore prestabilito se non vengono
valorizzati
Esempio
def func(a, b = 0):
print(a,b)
x = 1
y = 2
print func(x, y)
→ Output:
1 2
print func(x)
→ Output:
1 0
Funzioni con Numero di Parametri Variabile
Numero variabile di argomenti → utilizzo degli asterischi
*… → lista di parametri
**… → dizionario di parametri
Esempio
def func(*args,**kwargs):
print 'lista di parametri:', args
print 'dizionario di parametri:', kwargs
func(1, 2, 3 , b = 4, c = 5)
Output:
lista di parametri:
(1, 2, 3)
dizionario di parametri:
{'c': 5, 'b': 4}
Funzioni Lambda
Funzioni inline anonime, identificate dalla keyword lambda
Sintassi:
lambda <argomenti> : <espressione>
Equivalente ad un funzione con argomenti argomenti e con
valore di ritorno espressione.
g = lambda x: x**2
print 'g(2):', g(2)
print 'g:(4)', g(4)
Output:
g(2): 4
g(4): 16
List Comprehension
Modalità di estrazione di sottoinsiemi da liste (o dizionari).
Permette di agire sugli elementi dell’insieme e filtrarli allo
stesso tempo.
Operazioni iterative più immediate, flessibili ed efficienti
rispetto alle consuete istruzioni cicliche
Sintassi
lista = [espressione for variabile in altra_lista <if altra_espressione>]
List Comprehension
Esempio: data una lista a, creare una lista contenente i quadrati degli
elementi di a
a = [1, 2, 3, 4]
b = [x**2 for x in a]
print b
Output → [1, 4, 9, 16]
Esempio 2: data una lista a, creare una lista contenentegli elementi di a
che siano maggiori o uguali a 2
a = [1, 4, 2, 0, 3]
b = [x for x in a if x >= 2]
print b
Output → [4, 2, 3]
Gestione delle Eccezioni
Eccezione: errore rilevati durante l'esecuzione.
Senza nessun accorgimento: interruzione dell'esecuzione
a, b = 5, 0
print a / b
Output:
traceback (most recent call last):
File “<pyshell#5>”, line 1, in ?
print a / b
ZeroDivisionError: integer division or modulo
by zero
Gestione delle Eccezioni
Gestire le eccezioni - sintassi:
try:
<gruppo di istruzioni sotto test>
except <nome della classe di errore>:
<gruppo di istruzioni da eseguire in caso di errore>
else: #opzionale
<gruppo di istruzioni2>
Gestione delle Eccezioni
Esempio:
a, b = 5, 0
try:
print a / b
except ZeroDivisionError:
print ‘Errore: divisione per zero!'
Output: ‘Errore: divisione per zero!'
Iteratori
Iteratore: oggetto che consente di visitare tutti gli elementi contenuti in un
altro oggetto.
Il ciclo for usa implicitamente un iteratore.
Maniera esplicita:
iter() → crea un iteratore.
next() → rende l'elemento successivo
Esempio:
it = iter(sequence)
try:
while True:
print it.next()
except StopIteration:
pass
Generatori
Strumenti per creare iteratori.
Sono scritti come funzioni regolari, ma usano l'istruzione yield ogni qualvolta
restituiscano dei dati.
Esempio:
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
for char in reverse('golf'):
print char
Output:
f
l
o
g
Decoratori
Decoratore: funzione che modifica un'altra funzione.
Python passa la funzione da decorare al decoratore, e la sostituisce con il risultato.
Esempio:
def myDecorator(function):
print 'I am decorating!'
return function
def hello():
print 'hello world!'
hello = myDecorator(hello)
hello()
Output:
I am decorating!
hello world!
Decoratori
Python fornisce una sintassi specifica, che rende più leggibile il codice.
Esempio:
def myDecorator(function):
print 'I am decorating!'
return function
@myDecorator
def hello():
print 'hello world!'
hello()
Output:
I am decorating!
hello world!
Programmazione Orientata
agli Oggetti
Classi in Python
Sintassi:
class <nome classe> [(<classe madre>,…)]:
<elenco dati membro da inizializzare>
<elenco metodi>
Dati membro → espressi come normali variabili, inizializzate mediante
semplice assegnamento o definiti al momento dell’utilizzo.
Metodi → stessa sintassi delle funzioni, con alcuni accorgimenti: devono
avere come primo parametro l’oggetto stesso → parametro self.
Esempio:
class myClass:
i = 10
def func(self):
return 'Hello world'
Classi in Python
Sintassi:
class <nome classe> [(<classe madre>,…)]:
<elenco dati membro da inizializzare>
<elenco metodi>
Dati membro → espressi come normali variabili, inizializzate mediante
semplice assegnamento o definiti al momento dell’utilizzo.
Metodi → stessa sintassi delle funzioni, con alcuni accorgimenti: devono
avere come primo parametro l’oggetto stesso → parametro self.
Esempio:
Nome classe
class myClass:
Dato membro
i = 10
def func(self):
Metodo
return 'Hello world'
Classi in Python
Istanza di un oggetto:
a = myClass()
a è un oggetto della classe myClass, che contiene l'attributo i e il metodo
func
print a.i
→ Output: 10
a.f()
→ Output: Hello world
Classi in Python: Creazione e Inizializzazione
A differenza di altri linguaggi, gli oggetti sono costruiti e inizializzati
in due passi successivi separati:
__new__ → restituisce istanza non inizializzata
__init__ → inizializza l'istanza
Sono richiamate automaticamente in fase di creazione di un'istanza:
a = MyClass(…)
equivale a:
a = MyClass.__new__(…)
a.__init__(…)
Se non trovate, implicitamente vengono richiamate dalla classe object
(da cui derivano implicitamente tutti gli oggetti del linguaggio)
Classi in Python: Creazione e Inizializzazione
Inizializzazione: metodo __init__
Esempio:
class myClass:
def __init__(self, x):
self.i = x
a = myClass(10)
print a.i
→ Output: 10
Classi in Python: Metodi
N.B. Convenzionalmente, il primo argomento dei metodi è chiamato
self. Questa non è niente di più che una convenzione: il nome non ha
assolutamente alcun significato speciale in Python.
class myClass:
def __init__(pincopallino, x):
pincopallino.i = x
a = myClass(10)
print a.i
→ Output: 10
Classi in Python: Attributi
In molti linguaggi gli oggetti hanno un numero e un tipo di attributi
predeterminati dalla classe.
In Python oggetti della stessa classe possono avere attributi differenti
__init__ non vincola il numero di attributi di un oggetto.
class myClass:
def __init__(self, x):
self.i = x
a = myClass(10)
a.y = 5
print a.y
→ Output: 5
Classi in Python: Oggetti Funzione
Qualsiasi oggetto funzione che sia attributo di una classe definisce un
metodo per le istanze di tale classe.
Non è necessario la definizione di funzione sia racchiusa nella classe
def f(self):
return 'Hello world'
class myClass:
func = f
def g(self, x):
print x
h = g
a = myClass()
a.func()
→ Output: 'Hello world'
a.h(2)
→ Output: 2
Classi in Python: Variabili Private
Sintassi: come minimo due trattini bassi all'inizio, al più un trattino basso
in coda:
class myClass:
def __init__(self, a):
self.__x = a
Al di fuori della classe non si può accedere all'attributo privato:
a = myClass(10)
a.__x → Output: AttributeError: myClass instance has
no attribute '__x'
Classi in Python: Variabili Private
In realtà nulla in Python è realmente privato!!!
I nomi dei metodi e degli attributi privati vengono cambiati a livello di codice
eseguito:
__attributoPrivato → _NomeClasse__attributoPrivato
Esempio:
class myClass:
def __init__(self, a):
self.__x = a
a = myClass(10)
a._myClass__x → Output: 10
Gli attributi privati essenzialmente permettno alle sottoclassi di usare attributi con
lo stesso nome senza modificare il comportamento di eventuali metodi che ne
facevano uso
Classi in Python: Property
Consentono di costruire un “attributo virtuale” che richiama delle funzioni
(in lettura, scrittura, cancellazione).
Si definiscono richiamando la funzione built-in property:
x = property(fget=None, fset=None fdel=None)
fget → richiama la funzione di lettura dell'attributo
fget → richiama la funzione di scrittura dell'attributo
fdel → richiama la funzione di cancellazione dell'attributo
Se non specificate non è possibile effettuare l'operazione associata.
Classi in Python: Property
Esempio:
class myClass:
def __init__(self, x):
self.__x = x
def getX(self):
return self.__x
def setX(self,value):
self.__x=value
x = property(fget = getX, fset=setX)
a = myClass(10)
a.x = 20 #richiama setX
print a.x #richiama getX
Classi in Python: Property
Esempio:
class myClass:
def __init__(self, x):
self.__x = x
def setX(self,value):
self.__x=value
x = property(fset=setX)
a = myClass(10)
a.x = 20 #richiama setX
print
a.x
#restituisce
unreadable attribute'
un
errore:
'AttributeError:
Classi in Python: Overloading degli Operatori
Gli operatori algebrici possono essere ridefiniti, facendoli corrispondere a
funzioni speciali della classe
In questo modo e' possibile definire operazioni fra oggetti complessi con la
sintassi delle normali operazioni algebriche.
Questo viene fatto definendo le funzioni speciali; queste sono le funzioni
vengono chiamate da Python quando incontra operazioni fra istanze della
classe.
Esempio di funzioni speciali
__add__(a, b) # a + b
__sub__(a, b) # a - b
__mul__(a, b) # a * b
__div__(a, b) # a / b
…
Classi in Python: Overloading degli Operatori
Esempio di overloading: addizione
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, point):
self.x += point.x
self.y += point.y
a = Point(1,2)
b = Point(3,4)
a + b
print a.x, a.y
→ Output: 4 6
Classi in Python: Metodi Statici
Si comportano come funzioni globali dentro il namespace della classe.
Simili ai metodi statici di Java e C++
Sintassi: o tramite metodo staticmethod o tramite decoratore
@staticmethod.
In entrambi i casi non si devono passare parametri impliciti (self)
Esempio: data la classe
class P():
…
def f():
print 'Hello world'
Classi in Python: Metodi Statici
Rendere f() statico tramite metodo staticmethod:
class P():
…
def f():
print 'Hello world'
f = staticmethod(f)
…
Tramite decoratore:
class P():
…
@staticmethod
def f():
print 'Hello world'
f = staticmethod(f)
…
Classi in Python: Metodi Statici
In entrambi i casi, i metodi statici possono essere chiamati sia dalla classe
che da un'istanza della classe
a = P()
a.f()
→ 'Hello world'
P.f()
→ 'Hello world'
Classi in Python: Ereditarietà
Sintassi:
class NomeClasseDerivata(NomeClasseBase):
<istruzione-1>
…
<istruzione-N>
Al posto di NomeClasseBase è permessa anche un'espressione, utile quando
la classe base è definita in un altro modulo:
class NomeClasseDerivata(nomemodulo.NomeClasseBase)
Se un attributo non viene rinvenuto nella classe, viene cercato nella classe
base. Tale regola viene applicata ricorsivamente se la classe base è a sua volta
derivata da una qualche altra classe
Classi in Python: Ereditarietà
Esempio:
class A:
def __init__(self):
self.x = 1
class B(A):
def __init__(self):
A.__init__(self)
self.x = 2
b = B()
print b.x, b.y
→ Output: 1 2
A
A
BB
Classi in Python: Ereditarietà Multipla
Definizione di classe con classi base multiple:
class NomeClasseDerivata(Base1, Base2, … ):
<istruzione-1>
…
<istruzione-N>
Esempio:
class C(A,B):
…
BB
A
A
CC
Classi in Python: Ereditarietà Multipla
Regola di risoluzione usata per i riferimenti agli attributi di classe:
Prima-in-profondità
Poi da-sinistra-a-destra.
A
A
CC
BB
D
D
D→B→A→C
Classi in Python: Classe object
object è la classe di base da cui ereditano tutti i tipi built-in (list,
dict, str...) e tutte le classi definite dal programmatore, in maniera
implicita, esplicita, o indiretta (es. ereditando da tipi built-in).
class MyClass():
…
equivale a:
class MyClass(object):
…
Classi in Python: Polimorfismo
Funzione polimorfica → assume una forma diversa in base al tipo di
oggetto sul quale viene applicato.
Esempio:
class Gatto():
def verso(self):
return 'Miao'
class Cane():
def verso(self):
return 'Bau'
a = Gatto()
b = Gatto()
a.verso()
→ Output: 'Miao'
b.verso()
→ Output: 'Bau'
Metaclassi (cenni)
Metaclasse → classe le cui istanze sono a loro volta classi.
Internamente Python crea le classi istanziando la metaclasse type
E' possibile estendere la metaclasse type per creare una propria
metaclasse, ridefinendo i metodi __init__ e __new__
Per utilizzare la propria metaclasse invece della metaclesse type si usa una
sintassi del tipo:
class nomeclassse(metaclass = nomemetaclasse):
Python3
Tutte le slide precedenti sono relative alle versioni Python
2.XX
Python 3.0 è stato rilasciato nel 2008. L’obiettivo è stato
quello di ripulire il codice base e rimuovere la ridondanza,
mettendo in chiaro che c’è un solo modo per eseguire un
determinato compito.
Successivamente al rilascio del Python 3.0 nel 2008 , Python
2.7 è stato pubblicato il 3 luglio 2010 e previsto come l’ultimo
dei rilasci 2.x.
Python3: Differenze con Python 2
print → non più una istruzione ma una funzione
print 'Hello world' → print('Hello World')
Divisione fra interi. In Python2 ritorna un intero troncando il
risultato, in Python3 restituisce un float (anche se il risultato è
un intero)
range → restituisce non più una lista
file eliminata
…
Python2.7: Utilizzo di Funzioni Python 3
E' possibile importare funzionalità di Python3 col modulo
__future__
Ad esempio, per importare la funzionalità di divisione tra
interi di Python3:
from __future__ import division
…
a = 5/2
print a → 2.5
N.B. In Python 2 l'output sarebbe stato: 2
Python2 o Python3?
Python 3 continuerà ad essere sostenuto e sviluppato,
mentre Python 2.7 no (non più supportato dal 2020).
Python 2.7 è vista come release intermedia tra le versioni
precedenti di Python 2 e Python 3.0, e continua ad essere una
scelta molto popolare per i programmatori (e soprattutto dalle
aziende) grazie alla sua compatibilità con molte solide librerie.
Applicazioni
Sviluppo Web
framework leggeri → Bottle,
Bottle Webpy,
Webpy Flask …
framework di sviluppo web → Django,
Django TurboGears …
web application → Zope e il suo CMS Plone
framework Twisted → per scrivere servizi di rete
CGI (Common Gateway Interface) scripts
creazione di socket...
Applicazioni
Accesso ai database: modalità di accesso → DB-API.
Supporta nativamente diversi database (relazionali o nonrelazionali), oltre ad essere disponibili attraverso ODBC.
Oracle
MySQL
PostgreSQL
SQL Server
SQLite
Applicazioni
Applicazioni desktop e grafiche
libreria di sviluppo TkInter
wxPython (fusione della libreria C++ wxWidgets con Python)
PyQt
PyGTK
GenroPy → framework applicativi web che si presentano come
applicativi desktop
Applicazioni
Giochi e grafica 3D: Python è ampiamente usato per lo
sviluppo di giochi sia a livello commerciale che "hobbistico".
PyGame
PyKyra
Motori di Rendering 3D
Applicazioni
Calcolo scientifico e numerico: Python è ampiamente usato
in ambiente scientifico
MatPlotLib → tool per grafici 2D e 3D
NumPY → libreria per analisi statistiche e matriciali
SK-Learn → funzioni di calcolo scientifico e intelligenza
artificiale
Conclusione: Usare Python o no?
Vantaggi principali
Qualità
Produttività di sviluppo
Portabilità
Svantaggio principale
Linguaggio non compilato
The End!!!