In questa sezione descriviamo come specificare il formato con cui stampare le informazioni sia sullo shermo che in un file.
La funzione print
è il comando utilizzato più comunemente per stampare informazioni sullo “standard output device” che normalmente è lo schermo.
Ci sono due modi per usare print.
Il modo più facile di usare il comando print
è passargli l'elenco delle variabili da stampare separate da un virgola. Qualche esempio:
a = 10
b = 'test text'
print(a)
print(b)
print(a, b)
print("The answer is", a)
print("The answer is", a, "and the string contains", b)
Python aggiunge uno spazio tra ogni coppia di oggetti che viene stampata.
Python va a capo dopo ogni chiamata a print. Per impedirlo, usate il parametro end=
:
# Comportamento di default
print("Printing in line one")
print("...still printing in line one (just kidding).")
# sostituendo il simbolo di 'a capo' (\n) con uno spazio nel primo statement'
print("Printing in line one",end=" ")
print("...still printing in line one (now it works).")
È sufficiente mettere il simbolo f
, da cui il nome f-strings, di fronte al delimitatore iniziale della stringa e poi, all'interno della stringa stessa specificare variabile e formato fra parentesi graffe.
print(f"{'Susan'} needs {2} pints")
In genere è conveniente passare i valori da stampare attravero delle variabili:
name = 'Peter'
n = 4
print(f"{name} needs {n} pints")
Il formato con cui la variabile viene stampata si può specificare con una istruzione del tipo W.DF
per i numeri reali e del tipo W.F
per gli interi.
L'istruzione segue il nome della variabile da cui è separata dal simbolo ':'.
W
(width), che è opzionale, definisce il numero minimo di caratteri utilizzati per la scrittura; D
(digits), che è necessario, definisce il numero di cifre dopo il punto decimale; F
definisce lo stile.
La lista dei formati più comuni usando come esempio l'unità astronomica (distanza media Sole-Terra in metri): AU = 149597870700 m.
specifier | style | Example output for AU |
---|---|---|
f |
floating point | 149597870700.000000 |
e |
exponential notation | 1.495979e+11 |
g |
shorter of %e or %f | 1.49598e+11 |
d |
integer | 149597870700 |
x |
exadecimal | 22d4ba5a6c |
o |
octal | 2132456455154 |
s |
str() |
149597870700 |
AU = 149597870700 # unità astronomica [m]
AU_f = f"{AU:f}" # Stile float con parametri di default
print(AU_f)
AU_f1 = f"{AU:.1f}" # Stile float con una sola cifra dopo il punto
print(AU_f1)
AU_e = f"{AU:e}" # Stile esponenziale. Ha una cifra prima del punto.
print(AU_e)
AU_e4 = f"{AU:.4e}" # Stile esponenziale con quattro cifre dopo il punto
print(AU_e4)
Un numero prima del punto indica il numero minimo di spazi da riservare alla scrittura della variabile:
AU_f30_4 = f"**{AU:30.4f}**" # Stile float larghezza minima di 30 caratteri
# con quattro cifre dopo il punto.
# I caratteri * servono a rendere visibile lo spazio riservato
print(AU_f30_4)
Se si riservano un numero di spazi insufficiente la richiesta viene ignorata:
AU_f5_4 = f"**{AU:5.4f}**" # Stile float larghezza minima di 30 caratteri
# con quattro cifre dopo il punto.
# I caratteri * servono a rendere visibile lo spazio riservato
print(AU_f5_4)
Si possono utilizzare formati diversi in una singola stringa:
import math
print(f"{3*math.pi:10.8f} --- {math.pi:7.3e}")
Quando è necessario costruire f-strings che si estendono su più righe il metodo
più semplice è usare """
per delimitare la stringa
print(f"""prima riga
seconda riga""")
Il simbolo >, <, ^ allinea le variabili a destra, sinistra, centro dello spazio disponibile. L'allineamento a destra è il default per le variabili numeriche; l'allineamento a sinistra è il default per quasi tutte gli altri tipi di variabili.
Table = [[1,2,3],[5,6,7],[8,9,10]]
info = ["dato 1","dato 2","dato 3"]
print(f"{info[0]:>8s} {info[1]:>8s} {info[2]:>8s}")
print(30*'-')
for i in range(len(Table)):
print(f"{Table[i][0]:8d} {Table[i][1]:8d} {Table[i][2]:8d}")
# print(f"{Table[i][0]:i8} {Table[i][1]:i8} {Table[i][2]:i8}")
Separando più chiaramente le colonne
Table = [[1,2,3],[5,6,7],[8,9,10]]
info = ["dato 1","dato 2","dato 3"]
print(34*'-')
print(f"| {info[0]:>8s} | {info[1]:>8s} | {info[2]:>8s} |")
print(34*'-')
for i in range(len(Table)):
print(f"| {Table[i][0]:8d} | {Table[i][1]:8d} | {Table[i][2]:8d} |")
print(34*'-')
Effetto di allineamenti diversi:
Table = [[1,2,3],[5,6,7],[8,9,10]]
info = ["dato 1","dato 2","dato 3"]
print(34*'-')
print(f"| {info[0]:8s} | {info[1]:^8s} | {info[2]:>8s} |")
print(34*'-')
for i in range(len(Table)):
print(f"| {Table[i][0]:^8d} | {Table[i][1]:<8d} | {Table[i][2]:8d} |")
print(34*'-')
# print(f"{Table[i][0]:i8} {Table[i][1]:i8} {Table[i][2]:i8}")
Come incolonnare numeri reali e interi richiedendo lo stesso numero di cifre dopo il punto di separazione:
Table = [[1.2,2,3.14],[-5.0,6.17,7],[8,9,10]]
info = ["dato 1","dato 2","dato3"]
print(f"{info[0]:>12s} {info[1]:>12s} {info[1]:>12s}")
print(42*'-')
for i in range(len(Table)):
print(f"{Table[i][0]:12.2f} {Table[i][1]:12.2f} {Table[i][2]:12.2f}")
# print(f"{Table[i][0]:i8} {Table[i][1]:i8} {Table[i][2]:i8}")
format
¶Spesso si trovano esempi di una notazione più datata per specificare il formato di scrittura di una stringa che utilizza il metodo format
. La specificazione del formato è quella già vista nel caso delle f-string
. Mentre le istruzioni di formattazione sono all'interno della stringa da stampare, racchiuse da parentesi graffe,
i corrispondenti dati sono passati attraverso il metodo format
.
Le idee fondamentali attraverso esempi:
I valori vengono passati nell'ordine in cui devono comparire:
print("{} needs {} pints".format('Peter',4))
Alternativamente, si può passare l'ordine in cui vanno stampate le variabile usando l'indice all'interno delle parentesi graffe:
"{0} needs {1} pints".format('Peter', 4)
print("{1} needs {0} pints".format('Peter', 4))
Un'altra possibilità è di associare un nome a ciascuna variabile e usare il nome nelle parentesi graffe:
print("{name} needs {number} pints".format(name='Peter',number=4))
Le istruzioni di formattazione vanno all'interno delle parentesi graffe, precedute dal simbolo :
:
import math
print("Pi is approximately {:.2f}.".format(math.pi))
"Pi is approximately {:6.2f}.".format(math.pi)
Un esempio di come mescolare formati e ordine delle variabili:
"{1:10.8f} --- {0:7.3e} pints".format(3*math.pi, math.pi)
Ecco un programmma che
crea un file di nome test.txt
,
scrive del testo nel file,
chiude il file.
I dati che vengono immagazzinati nel file test.txt
sono:
Writing text to file. This is the first line.
And the second line.
Third line!!!!!!!
# 1. Scrivere in un file
out_file = open("test.txt", "w") # Il file viene aperto/creato in scrittura.
# 'w' vuol dire write.
out_file.write("Writing text to file. This is the first line.\n"+\
"And the second line.\n Third line!!!!!!!")
# Il singolo carattere "\n" segnala la fine di una riga. Vuol dire "a capo".
out_file.close() # chiude il file
La cella seguente
apre il file di nome test.txt
,
legge il testo dal file,
stampa il testo sullo schermo.
chiude il file
# 2. Leggere dal file
in_file = open("test.txt", "r") # Il file viene aperto in lettura. 'r' vuol dire read.
text = in_file.read() # Legge tutto il file in una variabile "text" di
# tipo stringa
in_file.close() # chiude il file
# 3. Mostrare i dati
print(text)
Più in dettaglio, il file viene aperto con il comando open
. L'oggetto file aperto viene assegnato alla variabile out_file
. Il testo viene scritto nel file usando il metodo out_file.write
. Si noti che nell'esempio più sopra, al metodo write
è stata passata una stringa. Si possono usare, ovviamente, tutte specificazioni di formato discusse in precedenza — si veda formatted printing e new style formatting. È buona pratica usare close()
su tutti i files in cui si è finito di leggere e scrivere. Se un programma Python finisce in modo controllato (cioè non per una caduta di tensione o un improbabile bug del linguaggio o del sistema operativo) tutti i files aperti vengono chiusi non appena i file objects vengono distrutti. Tuttavia, chiuderli esplicitamente non appena possibile è uno stile migliore di programmazione.
Creiamo un file chiamato myfile.txt
che contiene le tre linee di testo seguenti:
This is the first line.
This is the second line.
This is a third and last line.
Il metodo write non aggiunge il carattere newline (\n)
alla fine di ogni operazione di scrittura
f = open('myfile.txt', 'w')
f.write('This is the first line.\n'
'This is the second line.\n'
'This is the third and last line.')
f.close()
Modi equivalenti:
f1 = open('myfile1.txt', 'w')
f1.write('This is the first line.\n''This is the second line.\n''This is the third and last line.')
f1.close()
f2 = open('myfile2.txt', 'w')
f2.write('This is the first line.\n'+'This is the second line.\n'+'This is the third and last line.')
f2.close()
È sbagliato passare a write
più stringhe separate da virgole. write
accetta un solo argomento.
f3 = open('myfile3.txt', 'w')
f3.write('This is the first line.\n','This is the second line.\n','This is the third and last line.')
f3.close()
Il metodo fileobject.read()
legge tutto il file, e lo restituisce come una singola stringa (inclusi i caratteri di "a capo" \n
).
f = open('myfile.txt', 'r')
f.read()
f.close()
Il metodo fileobject.readlines()
restituisce una lista di stringhe, in cui ciascun elemento della lista corrisponde a una linea del file:
f = open('myfile.txt', 'r')
f.readlines()
f.close()
Questo metodo viene spesso utilizzato per iterare sulle linee, compiendo delle operzioni su ciascuna linea. Per esempio:
f = open('myfile.txt', 'r')
for line in f.readlines():
print(f"{len(line)} characters")
f.close()
Si noti che readlines()
immagazzina tutto il file in una lista di stringhe. Non è un problema se si è sicuri che il file è piccolo e che può essere contenuto nella memoria disponibile.
In questo caso, possiamo chiudere il file prima di processarne il contenuto:
f = open('myfile.txt', 'r')
lines = f.readlines()
f.close()
for line in lines:
print("%d characters %s" % (len(line),line))
Python considera un file come una lista di linee così come una stringa viene considerata come una lista di caratteri. Possiamo quindi utlizzare la list comprehension
per leggere un file linea per linea. Questo approccio è adatto anche a files grandi e produce un codice compatto:
f = open('myfile.txt', 'r')
for line in f:
print(f"{len(line)} characters")
f.close()
In questo caso, il "file handle" f
agisce come un iteratore e restituisce la linea seguente a ogni iterazione del for-loop fino alla fine del file (quando il for-loop finisce). In alternativa si può usare il metodo readline
che restituisce una riga alla volta:
f = open('myfile.txt', 'r')
l1 = f.readline()
print(l1)
l2 = f.readline()
print(l2)
f.close()
with
¶La documentazione di Python consiglia accedere ai file con la keyword with
:
with open('myfile.txt',"r") as f:
for line in f:
print(f"{len(line)} characters")
Questa notazione chiude automaticamente il file alla fine delle operazioni contenute nel blocco with
anche se il programma si fermasse per un errore. Il comando close
non è più necessario.
La directory di lavoro si trova con il comando (magico)
%pwd
Si può aprire un file già esistente utilizzando il path assoluto:
with open(r"/Users/maina/cernbox/python/MyCourse/path_test_dir/pippo1.txt","r") as filein:
for line in filein:
print(f"{line} :: {len(line)} characters")
Si può creare un nuovo file utilizzando il path assoluto e passando il parametro "w"
al comando open
:
lines = ["pippo", "pluto", "non c'è trippa per gatti"]
with open(r"/Users/maina/cernbox/python/MyCourse/path_test_dir/pippo2.txt","w") as fileout:
for line in lines:
fileout.write(line+"\n")
Check:
test = open(r"/Users/maina/cernbox/python/MyCourse/path_test_dir/pippo2.txt","r")
res = test.read()
print(res)
res
Si può aprire un file già esistente utilizzando il path relativo:
with open(r"../path_test_dir/pippo1.txt","r") as filein:
for line in filein:
print(f"{line} :: {len(line)} characters")
Notate come nelle celle precedenti il path venga passato in stringhe che hanno la lettera r
prima del delimitatore. Questo tipi di stringhe si chiamano raw strings
. Tutto il testo contenuto nella stringa viene scritto esattamente come appare, per esempio "\n" viene interpretato come backslash
+ n
e non come il simbolo di a capo
.
print
semplice¶print
stampa informazioni sullo standard output, solitamente lo schermo.print
va a capo alla fine di ogni chiamata, ma questo comportamento può essere modificato usando il parametro end=
.Le f-strings sono un metodo recente e semplice per specificare il formato di stampa.
Si inserisce f
prima della stringa, e le variabili con formato sono racchiuse tra parentesi graffe {}
.
Specificatori di formato:
{nome_var}:W.DF per i numeri reali ({ }:W.F per gli interi) dove W (width, opzionale) è il numero minimo di caratteri; D (digits, necessaria) è il numero di cifre dopo il punto decimale; F definisce lo stile. Per esempio
f
: punto mobile
e
: notazione esponenziale
d
: intero
s
: stringa
Allineamento
>
, <
, ^
per destra, sinistra e centro.open("nomefile", "w")
.write()
per scrivere nel file.close()
.open("nomefile", "r")
.read()
oppure readlines()
per leggere il contenuto del file.list comprehension
per leggere il contenuto del file una riga alla volta.close()
.