Cominciare ad usare Python - Parte 2
Questa è la continuazione della precedente Parte 1 su Python dove avevo illustrato alcune funzioni base tramite l'uso diretto della console interattiva (py.exe / python3).
In questa parte illustro la gestione delle eccezioni, l'uso delle funzioni, i moduli e le classi.
L'esecuzione del codice avviene con la sintassi
Il modo migliore per gestire i file è usare visual Studio Code
Python, per questo scopo, mette a disposizione le istruzioni try except else finally nella forma
nella parte except si possono gestire vari tipi di eccezioni, ad esempio
questo codice stampa a video
Volendo posso anche sollevare un eccezione da codice tramite il comando raise nome_eccezione
ad esempio la funzione
l'esempio produce questo risultato
da come risultato
Oppure posso usare **kwargs per passare dei parametri in numero variabile per nome
da come risultato
Ogni modulo è un diverso file con estensione .py.
Ad esempio possiamo creare un modulo di nome helpers.py con una libreria di nostre funzioni di utilità generale
in questo caso una funzione per stampare un log nella console e una per sommare due numeri.
Per usarlo in un altro file, dobbiamo prima importarlo con import nome_modulo
se non servono tutte le funzioni, è inutile importare tutto il modulo, si può importare solo quella che serve con le keyword from ... import ...
posso importare tutte le funzioni con l'asterisco *
nel caso il nome della funzione andasse in conflitto con un'altra già esistente, posso rinominarla con la keyword as
infine, nel caso avessi un conflitto a livello di nome del modulo, posso rinominare tutto il modulo
La sintassi per definire una classe è la seguente che fa uso della keyword class
istanziamole, macchina_uno e macchina_due'',' invocando metodi''' (il risultato è nei commenti)
Rivedi la Parte 1 oppure prosegui con la Parte 3
In questa parte illustro la gestione delle eccezioni, l'uso delle funzioni, i moduli e le classi.
Uso dei file
L'uso della console interattiva va bene per piccole prove, appena si deve creare qualche cosa di più complesso conviene creare un file, con estensione .py dove scrivere il proprio codice.L'esecuzione del codice avviene con la sintassi
PowerShell
# windows
py .\nome_file.py
# linux
python3 .\nome_file.py
Il modo migliore per gestire i file è usare visual Studio Code
Eccezioni
Una parte importante di ogni programma è la corretta gestione delle eccezioni.Python, per questo scopo, mette a disposizione le istruzioni try except else finally nella forma
Python
try:
# codice che potrebbe generare un eccezione
except:
# gestione dell'eccezione
else:
# opzionale
# eseguita solo se NON vengono sollevate eccezioni
finally:
# opzionale
# istruzioni eseguite sempre
# sia quando va tutto bene che dopo la gestione dell'eccezione
Python
#x = 1 # prova a togliere il commento
y = 0 # prova con y = 0
try:
print(x / y)
except ZeroDivisionError as e:
# qui gestisco solo le eccezioni di tipo ZeroDivisionError
print("div by zero")
except:
# quella generica deve essere l'ultima
print("error")
else:
print("else")
finally:
print("finally")
- con x non definita => error, finally
- con x=1 e y=1 => 1.0, else, finally
- con x=1 e y=0 => div by zero, finally
Python
tabellina = input("Tabellina: ")
try:
t = int(tabellina)
for n in range(1, 11):
print(f"{n} x {t} = {n * t}")
except:
print('Numero non valido')
Volendo posso anche sollevare un eccezione da codice tramite il comando raise nome_eccezione
Python
# sollevo un eccezione specifica
raise ValueError
# all'interno di except: rilancio l'eccezione corrente
try:
# eventuale errore
except:
print("errore")
# rilancio l'eccezione attuale
raise
Funzioni
Le funzioni in Python vengono definite tramite la keywork defPython
def nome_funzione(parametro1, parametro2, ...):
# corpo della funzione, con eventuale valore di ritorno
return valore
Python
from datetime import datetime
def print_time(message, show_message = True):
if show_message == True:
print(f"{datetime.now()} {message}")
else:
print(datetime.now())
print()
Da notare il parametro show_message a cui è stato assegnato un valore di default.
Per invocare una funzione si usa la sintassi nome_funzione(eventuali_parametri)Python
# ometto il parametro con il valore di default
print_time('Ora')
# richiamo la funzione passando i parametri per nome
print_time(message='test', show_message=False)
# in questo caso l'ordine dei parametri non è importante
print_time(message='test', show_message=False)
Text
2019-10-10 22:04:30.746470 Ora
2019-10-10 22:04:30.747469
2019-10-10 22:04:30.748468
Attenzione, la funzione deve essere definita nel file prima che venga richiamata, altrimenti viene sollevata un eccezione di funzione non definita:
Traceback (most recent call last):
File ".\app.py", line 13, in <module>
print_time('Ora')
NameError: name 'print_time' is not defined
Traceback (most recent call last):
File ".\app.py", line 13, in <module>
print_time('Ora')
NameError: name 'print_time' is not defined
Argomenti infiiti
E' possibile definire una funzione per rifare in modo che accetti un numero variabile di parametri tramite *argvPython
def fn_multi(p1, *argv):
print("p1", p1)
for p in argv:
print(p)
fn_multi("ciao", "come", "va", "altri parametri", "...")
Text
p1 ciao
come
va
altri parametri
...
Python
def fn_multi(**kwargs):
for key, value in kwargs.items():
print(key, value)
fn_multi(primo="ciao", par1="come", parN="va")
Text
primo ciao
par1 come
parN va
Da notare la sintassi del for per ciclare sia sul nome del parametro (key) che sul valore (value)
Moduli
Quando il codice diventa complesso, è impensabile gestire tutto in un unico file, conviene suddividere in codice in più parti, dette moduli, da richiamare quando necessario.Ogni modulo è un diverso file con estensione .py.
Ad esempio possiamo creare un modulo di nome helpers.py con una libreria di nostre funzioni di utilità generale
Python
# helpers.py
def display(message, is_warning=False):
if is_warning:
print(f"Warning!! {message}")
else:
print(message)
def somma(op1, op2):
return op1 + op2
La keyword return, nella funzione somma, viene usata per restituire il risultato della funzione.
Per usarlo in un altro file, dobbiamo prima importarlo con import nome_modulo
Python
# app.py
import helpers
# richiamo la funzione con la sintassi nome_modulo.nome_funzione
helpers.display("Funziona :-)", True)
# Warning!! Funziona :-)
print(helpers.somma(3, 5))
# 8
Python
# app.py
from helpers import display
# ho importato solo la funzione "display", la richiamo senza il prefisso del modulo
display("Ciao")
# Ciao
Python
from helpers import *
Python
# app.py
from helpers import display as prt
# non esiste la funzione "display" è diventata "prt"
prt("Ciao")
Python
# app.py
import helpers as mia_lib
print(mia_lib.somma(2,5))
# 7
Classi
Come dicevo nella Parte 1, Python è un linguaggio orientato agli oggetti.La sintassi per definire una classe è la seguente che fa uso della keyword class
Python
class NomeClasse:
proprieta_condivisa = valore
def __init__(self, parametro_1, parametro_2, ...):
# corpo del costruttore + proprietà
self.proprieta_1 = parametro_1
self.proprieta_2 = parametro_2
self.proprieta_N = parametro_N
def nome_metodo(self, parametro_a, parametro_b, ...):
# corpo del metodo
La convenzione per i nomi delle classi è quella di usare la notazione CamelCase
Gli aspetti su cui focalizzarsi sono:- la classe si definisce tramite la keyword class
- il costruttore è una funzione con il nome riservato __init__
- il primo parametro del costruttore e degli altri metodi deve sempre essere self
- le proprietà si definiscono con la sintassi self.nome_proprieta e sono valide a livello di istanza (es.: self.proprieta_1)
- le proprietà definite a livello di classe son condivise tra tutte le istanze (es.: proprieta_condivisa), vanno modificate con la sintassi NomeClasse.proprieta
Python
variabile = NomeClasse(eventuali_parametri)
Da nota la mancanza di una keyword prima del nome della classe, ad esempio new usata da JavaScript o C#
Per capire come funziona, creiamo una classe di esempio MacchinaPython
class Macchina:
# definisco una proprietà a livello di classe
modello = "Ford"
# quando istanzio la classe devo passare un identificativo e una velocità iniziale
def __init__(self, id_macchina, velocita):
self.velocita_attuale = velocita
self.id = id_macchina
# con questo metodo spengo il motore, velocità = 0
def spegni_motore(self):
self.velocita_attuale = 0
# con questo lo accendo ad un valore di default, velocità = 1
def accendi_motore(self):
self.velocita_attuale = 1
# con questo metodo posso impostare una velocità specifica
def imposta_velocita(self, velocita):
if velocita >= 0 and velocita < 10:
self.velocita_attuale = velocita
# questo metodo lo uso per cambiare la proprietà a livello di classe condivisa tra le istanze
def imposta_modello(self, modello):
# accesso alla proprietà a livello di classe
Macchina.modello = modello
# infine, un metodo che mi restituisce lo stato delle macchina
def info(self):
return f"Veicolo: {self.id}, velocità: {self.velocita_attuale}, modello: {Macchina.modello}"
Python
# creo due macchine
macchina_uno = Macchina(1, 3)
macchina_due = Macchina(2, 1)
print("Start:", macchina_uno.info(), "|", macchina_due.info())
# Start: Veicolo: 1, velocità: 3, modello: Ford | Veicolo: 2, velocità: 1, modello: Ford
macchina_uno.spegni_motore()
print("Spegni 1 =>", macchina_uno.info(), "|", macchina_due.info())
# Spegni 1 => Veicolo: 1, velocità: 0, modello: Ford | Veicolo: 2, velocità: 1, modello: Ford
macchina_uno.accendi_motore()
print("Accendi 1 =>", macchina_uno.info(), "|", macchina_due.info())
# Accendi 1 => Veicolo: 1, velocità: 1, modello: Ford | Veicolo: 2, velocità: 1, modello: Ford
macchina_uno.imposta_velocita(7)
print("Imposta 1 =>", macchina_uno.info(), "|", macchina_due.info())
# Imposta 1 => Veicolo: 1, velocità: 7, modello: Ford | Veicolo: 2, velocità: 1, modello: Ford
macchina_due.imposta_velocita(9)
print("Imposta 2 =>", macchina_uno.info(), "|", macchina_due.info())
# Imposta 2 => Veicolo: 1, velocità: 7, modello: Ford | Veicolo: 2, velocità: 9, modello: Ford
macchina_due.imposta_modello("Fiat")
print("Modello 2 =>", macchina_uno.info(), "|", macchina_due.info())
# Modello 2 => Veicolo: 1, velocità: 7, modello: Fiat | Veicolo: 2, velocità: 9, modello: Fiat
Rivedi la Parte 1 oppure prosegui con la Parte 3