Introduzione a Python

Premessa

Ti diamo il benvenuto nel tutorial online su Python di Google. Si basa sul corso Python introduttivo offerto internamente. Come menzionato nella pagina di configurazione, questo materiale riguarda Python 3.

Se stai cercando un corso MOOC complementare, prova quelli di Udacity e Coursera (introduzione alla programmazione [begins] o introduzione a Python). Infine, se sei alla ricerca di un apprendimento online autogestito senza guardare i video, prova quelli elencati alla fine di questo post. Ognuna include i contenuti didattici e un interprete interattivo Python con cui fare pratica. Cos'è questo "interprete" menzionate? Lo scoprirai nella prossima sezione.

Introduzione al linguaggio

Python è un linguaggio dinamico e interpretato (compilato con bytecode). Non ci sono dichiarazioni di tipo di variabili, parametri, funzioni o metodi nel codice sorgente. Questo rende il codice breve e flessibile e perdi il controllo del tipo di compilazione in fase di compilazione del codice sorgente. Python monitora i tipi di tutti i valori in fase di runtime e segnala il codice che non ha senso durante l'esecuzione.

Un modo eccellente per vedere come funziona il codice Python è eseguire l'interprete Python e digitare il codice direttamente al suo interno. Se ti è capitato di porre una domanda, ad esempio "Cosa succede se aggiungo un int a un list?" Basta digitarlo nell'interprete Python per vedere cosa succede, ma è probabilmente il modo migliore. Vedi di seguito per vedere cosa succede davvero.

$ python3        ## Run the Python interpreter
Python 3.X.X (XXX, XXX XX XXXX, XX:XX:XX) [XXX] on XXX
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 6       ## set a variable in this interpreter session
>>> a           ## entering an expression prints its value
6
>>> a + 2
8
>>> a = 'hi'    ## 'a' can hold a string just as well
>>> a
'hi'
>>> len(a)      ## call the len() function on a string
2
>>> a + len(a)  ## try something that doesn't work
Traceback (most recent call last):
  File "", line 1, in 
TypeError: can only concatenate str (not "int") to str
>>> a + str(len(a))  ## probably what you really wanted
'hi2'
>>> foo         ## try something else that doesn't work
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'foo' is not defined
>>> ^D          ## type CTRL-d to exit (CTRL-z in Windows/DOS terminal)

Le due righe che il pitone stampa dopo aver digitato Python e prima di >>> nel prompt parla di la versione di Python in uso e dove è stata creata. Purché la prima cosa stampata sia "Python 3.", questi esempi dovrebbero funzionare per te.

Come puoi vedere sopra, è facile sperimentare variabili e operatori. Inoltre, l'interprete lancia o "alza" nel linguaggio Python, si tratta di un errore di runtime se il codice cerca di leggere una variabile a cui non è stato assegnato un valore. Come C++ e Java, Python fa distinzione tra maiuscole e minuscole, quindi "a" e "A" sono variabili diverse. La fine di una riga segna la fine di un'istruzione, quindi, a differenza di C++ e Java, Python non richiede un punto e virgola alla fine di ogni istruzione. I commenti iniziano con "#" e si estendono fino alla fine della riga.

Codice sorgente Python

I file sorgente Python utilizzano il comando ".py" e sono chiamati "moduli". Con un modulo Python hello.py, il modo più semplice per eseguirlo è con il comando shell "python hello.py Alice" che chiama l'interprete Python per eseguire il codice in hello.py, passando l'argomento della riga di comando "Alice". Consulta la pagina della documentazione ufficiale per conoscere tutte le diverse opzioni a tua disposizione quando esegui Python dalla riga di comando.

Ecco un programma hello.py molto semplice (nota che i blocchi di codice sono delimitati rigorosamente tramite rientro anziché parentesi graffe. Ne parleremo più avanti):

#!/usr/bin/python3

# import modules used here -- sys is a very standard one
import sys

# Gather our code in a main() function
def main():
    print('Hello there', sys.argv[1])
    # Command line args are in sys.argv[1], sys.argv[2] ...
    # sys.argv[0] is the script name itself and can be ignored

# Standard boilerplate to call the main() function to begin
# the program.
if __name__ == '__main__':
    main()

L'esecuzione di questo programma dalla riga di comando è simile al seguente:

$ python3 hello.py Guido
Hello there Guido
$ ./hello.py Alice  ## without needing 'python3' first (Unix)
Hello there Alice

Importazioni, argomenti della riga di comando e len()

Le istruzioni più esterne di un file Python, o "module", eseguono la configurazione una tantum: vengono eseguite dall'alto verso il basso la prima volta che il modulo viene importato da qualche parte, impostando le sue variabili e funzioni. Un modulo Python può essere eseguito direttamente, come nell'esempio precedente python3 hello.py Bob, oppure importato e utilizzato da qualche altro modulo. Quando un file Python viene eseguito direttamente, la variabile speciale "__name__" è impostato su "__main__". Pertanto, è comune che il boilerplate if __name__ ==... mostrato sopra chiami una funzione main() quando il modulo viene eseguito direttamente, ma non quando viene importato da qualche altro modulo.

In un programma Python standard, l'elenco sys.argv contiene gli argomenti della riga di comando nel modo standard in cui sys.argv[0] è il programma stesso, sys.argv[1] è il primo argomento e così via. Se conosci argc, o il numero di argomenti, puoi semplicemente richiedere questo valore da Python con len(sys.argv), proprio come abbiamo fatto nel codice dell'interprete interattivo sopra riportato quando richiedi la lunghezza di una stringa. In generale, len() può indicare la lunghezza di una stringa, il numero di elementi negli elenchi e nelle tuple (un'altra struttura di dati simile a un array) e il numero di coppie chiave-valore in un dizionario.

Funzioni definite dall'utente

In Python, le funzioni sono definite in questo modo:

# Defines a "repeat" function that takes 2 arguments.
def repeat(s, exclaim):
    """
    Returns the string 's' repeated 3 times.
    If exclaim is true, add exclamation marks.
    """

    result = s + s + s # can also use "s * 3" which is faster (Why?)
    if exclaim:
        result = result + '!!!'
    return result

Nota anche che le righe che compongono la funzione o l'istruzione if sono raggruppate in base allo stesso livello di rientro. Abbiamo presentato anche 2 diversi modi per ripetere le stringhe, usando l'operatore + che è più facile da usare, ma * funziona anche perché è la "ripetizione" di Python operatore, il che significa che '-' * 10 offre a '----------', un modo semplice per creare una "riga" sullo schermo. Nel commento al codice, abbiamo suggerito che * funziona più velocemente di +, il motivo è che * calcola la dimensione dell'oggetto risultante una volta mentre, con +, tale calcolo viene effettuato ogni volta che viene chiamato +. Sia + che * sono denominati "sovraccarichi" perché hanno un significato diverso per i numeri e per le stringhe (e altri tipi di dati).

La parola chiave def definisce la funzione con i relativi parametri tra parentesi e il codice rientrato. La prima riga di una funzione può essere una stringa di documentazione ("docstring") che descrive lo scopo della funzione. Il docstring può essere costituito da una singola riga o una descrizione su più righe, come nell'esempio sopra. (Sì, si tratta di "Virgolette triple", una funzionalità unica di Python). Le variabili definite nella funzione sono locali rispetto a quella funzione, pertanto il "risultato" nella funzione precedente è separata da un "risultato" in un'altra funzione. L'istruzione return può prendere un argomento, nel qual caso questo è il valore restituito al chiamante.

Di seguito è riportato il codice che chiama la funzione ripeti() sopra riportata, stampando ciò che restituisce:

def main():
    print(repeat('Yay', False))      ## YayYayYay
    print(repeat('Woo Hoo', True))   ## Woo HooWoo HooWoo Hoo!!!

In fase di esecuzione, le funzioni devono essere definite dall'esecuzione di un comando "def" prima che venga chiamato. È tipico definire una funzione main() verso la parte inferiore del file con le funzioni chiamate sopra di essa.

Rientro

Una funzionalità Python insolita è che il rientro di una parte di codice in uno spazio vuoto influisce sul suo significato. Un blocco logico di istruzioni come quelle che compongono una funzione deve avere tutte lo stesso rientro, impostato dal rientro della funzione padre o dall'elemento "if" o altro. Se una delle righe di un gruppo ha un rientro diverso, viene segnalato come errore di sintassi.

L'uso dello spazio vuoto da parte di Python all'inizio sembra un po' strano, ma è logico e mi sono abituato molto rapidamente. Evita di usare le schede, in quanto complicano notevolmente lo schema di rientro (per non parlare delle TAB possono avere significati diversi su piattaforme diverse). Imposta l'editor per inserire spazi anziché TAB per il codice Python.

Una domanda frequente che i principianti si fanno è: "Quanti spazi devo far rientrare?". Secondo la guida di stile ufficiale per Python (PEP 8), devi applicare il rientro con 4 spazi. Curiosità: la linea guida di stile interna di Google impone il rientro di due spazi.

Codice verificato durante il runtime

Python esegue pochissimi controlli in fase di compilazione, rinviando quasi tutti i controlli di tipo, nome e così via su ogni riga fino all'esecuzione di quella riga. Supponiamo che la funzione main() sopra chiami ripeti() nel seguente modo:

def main():
    if name == 'Guido':
        print(repeeeet(name) + '!!!')
    else:
        print(repeat(name))

L'istruzione if contiene un errore evidente, in cui la funzione ripeti() viene accidentalmente digitata come repeeeet(). La cosa divertente in Python ... questo codice viene compilato e funziona bene purché il nome in fase di runtime non sia "Guido". Solo quando un'esecuzione tenta effettivamente di eseguire la funzione repeeeet(), noterà che non esiste questa funzione e viene generato un errore. In questo snippet è presente anche un secondo errore. non è stato assegnato un valore prima del confronto con "Guido". Python genererà un errore "NameError" se provi a valutare una variabile non assegnata. Questi sono alcuni esempi che dimostrano che quando esegui per la prima volta un programma Python, alcuni dei primi errori che vedrai saranno semplici errori di battitura o variabili non inizializzate come questi. Si tratta di un'area in cui i linguaggi con un sistema di tipi più dettagliato, come Java, hanno un vantaggio: possono rilevare questi errori al momento della compilazione (ma ovviamente devi gestire tutte le informazioni di quel tipo... è un compromesso).

Python 3 ha introdotto i suggerimenti relativi ai tipi. I suggerimenti relativi al tipo consentono di indicare il tipo per ogni argomento in una funzione e cosa qual è il tipo dell'oggetto restituito dalla funzione. Ad esempio, nella funzione annotata def is_positive(n: int) -> bool:, l'argomento n è un int e il valore restituito è bool. Vedremo cosa significano questi tipi più avanti. Tuttavia, i suggerimenti relativi al tipo sono del tutto facoltativi. Vedrai sempre più suggerimenti di tipo di adozione di codice perché, se li utilizzi, alcuni editor come cider-v e VS.code possono eseguire controlli per verificare che le tue funzioni vengano chiamate i tipi di argomenti giusti. Possono anche suggerire e convalidare gli argomenti durante la modifica del codice. Questo tutorial non riguarda i suggerimenti sui tipi, ma vogliamo assicurarci che tu sia a conoscenza del loro uso. o di vederli in natura.

Nomi variabili

Poiché le variabili Python non hanno alcun tipo scritto nel codice sorgente, è particolarmente utile assegnare nomi significativi alle variabili per ricordare ciò che sta succedendo. Quindi usa "name" se si tratta di un solo nome, e "nomi" se è un elenco di nomi e "tuple" se è un elenco di tuple. Molti errori di base di Python derivano dall'dimenticarsi del tipo di valore presente in ogni variabile, quindi usa i nomi delle variabili (tutto quello che hai a disposizione) per sistemare le cose.

Per quanto riguarda la denominazione effettiva, alcune lingue preferiscono underscored_parts per i nomi delle variabili composti da "più di una parola", mentre altre lingue preferiscono il cammello. In generale, Python preferisce il metodo del trattino basso, ma guida gli sviluppatori a concentrarsi su camelCasing se si integra nel codice Python esistente che già utilizza questo stile. La leggibilità è importante. Scopri di più nella sezione sulle convenzioni di denominazione in PPE 8.

Come puoi intuire, parole chiave come "se" e "Mentre" non possono essere utilizzati come nomi di variabili: se lo fai, riceverai un errore di sintassi. Tuttavia, fai attenzione a non usare gli elementi integrati come nomi delle variabili. Ad esempio, mentre "str", "list" e "print" possono sembrare buoni nomi, le variabili di sistema vengono sostituite. I componenti integrati non sono parole chiave e, di conseguenza, sono suscettibili all'uso involontario da parte dei nuovi sviluppatori Python.

Scopri di più sui moduli e sui relativi spazi dei nomi

Supponiamo che tu abbia un modulo "binky.py" che contiene "def foo()". Il nome completo della funzione foo è "binky.foo". In questo modo, i vari moduli Python possono denominare le loro funzioni e variabili come preferiscono, senza che siano in conflitto con i nomi delle variabili: modulo1.foo è diverso da modulo2.foo. Nel vocabolario Python, diremmo che binky, modulo1 e modulo2 hanno ciascuno i propri "spazi dei nomi", che, come puoi intuire, sono associazioni tra nome variabile e oggetto.

Ad esempio, abbiamo lo standard "sys" che contiene alcune strutture di sistema standard, come l'elenco di argomenti e la funzione exit(). Con l'istruzione "import sys" puoi quindi accedere alle definizioni nel modulo sys e renderle disponibili con il loro nome completo, ad esempio sys.exit(). Sì, anche "sys" ha uno spazio dei nomi.

  import sys

  # Now can refer to sys.xxx facilities
  sys.exit(0)

Esiste un altro modulo di importazione simile al seguente: "from sys import argv, exit". Ciò rende argv e exit() disponibili con i loro nomi brevi; Tuttavia, consigliamo di utilizzare il modulo originale con nomi completi perché è molto più facile determinare la provenienza di una funzione o di un attributo.

Esistono molti moduli e pacchetti che vengono forniti in bundle con un'installazione standard dell'interprete Python, quindi non devi fare altro per utilizzarli. Queste sono collettivamente note come "libreria standard Python". I moduli/pacchetti di uso più comune includono:

  • sys: accesso a exit(), argv, stdin, stdout, ...
  • re: espressioni regolari
  • sistema operativo: interfaccia del sistema operativo, file system

Puoi trovare la documentazione di tutti i moduli e i pacchetti della libreria standard all'indirizzo http://docs.python.org/library.

Guida online, help() e dir()

Esistono diversi modi per ricevere assistenza per Python.

  • Esegui una ricerca su Google iniziando con la parola "pitone", ad esempio "elenco pitoni" o "stringa Python in minuscolo". La prima risposta è spesso la risposta. Questa tecnica sembra funzionare meglio per Python che per altri linguaggi per qualche motivo.
  • Il sito ufficiale della documentazione Python - docs.python.org: offre documenti di alta qualità. Tuttavia, spesso faccio una ricerca su Google di un paio di parole per essere più veloce.
  • È disponibile anche una mailing list ufficiale per Tutor progettata appositamente per i nuovi utenti di Python e/o della programmazione.
  • Su StackOverflow e Quora puoi trovare molte domande (e risposte).
  • Usare le funzioni help() e dir() (vedi sotto).

All'interno dell'interprete Python, la funzione help() estrae stringhe di documentazione per vari moduli, funzioni e metodi. Queste stringhe di documenti sono simili al javadoc di Java. La funzione dir() indica quali sono gli attributi di un oggetto. Di seguito sono riportati alcuni modi per chiamare help() e dir() dall'interprete:

  • help(len): stringa di aiuto per la funzione len() integrata; si tratta di "len" non "len()", che è una chiamata alla funzione, che non vogliamo
  • help(sys) - stringa di aiuto per il modulo sys (deve eseguire prima un import sys)
  • dir(sys): dir() è simile a help() ma fornisce solo un breve elenco dei simboli definiti, o "attributi"
  • help(sys.exit): stringa di aiuto per la funzione exit() nel modulo sys
  • help('xyz'.split): stringa di aiuto per il metodo split() per gli oggetti stringa. Puoi chiamare help() con l'oggetto stesso o con un esempio di quell'oggetto, più il relativo attributo. Ad esempio, chiamare help('xyz'.split) equivale a chiamare help(str.split).
  • help(list): stringa di aiuto per list oggetti
  • dir(list): visualizza gli attributi dell'oggetto list, inclusi i relativi metodi
  • help(list.append): stringa di aiuto per il metodo append() per list oggetti