English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Tutorial di base di Python

Controllo dei flussi in Python

Funzione in Python

Tipi di dati in Python

Operazioni su file in Python

Oggetti e classi in Python

Data e ora in Python

Conoscenze avanzate di Python

Manuale di riferimento di Python

Chiusura in Python

In questo articolo, imparerai cosa sono i closure in Python, come definire i closure e le ragioni per cui si utilizzano i closure.

Variabili non locali nelle funzioni annidate

Prima di comprendere cosa sono i closure, dobbiamo prima comprendere cosa sono le funzioni annidate e le variabili non locali.

在另一个函数内部定义的函数称为嵌套函数。嵌套函数可以访问封闭范围的变量。

La funzione definita all'interno di un'altra funzione si chiama funzione annidata. La funzione annidata può accedere alle variabili del contesto chiuso.In Python, di default, queste variabili non locali sono di sola lettura e dobbiamo dichiararle esplicitamente come variabili non locali (usandoChiave nonlocal

) per poterli modificare.

Cosa succede se l'ultima riga della funzione print_msg() restituisce la funzione printer() invece di chiamarla? Questo significa che la definizione della funzione è come segue.
def print_msg(msg):
    # Questo è la funzione chiusa esterna
def printer():
        # Questo è la funzione annidata
    Ecco un esempio di funzione annidata che accede a variabili non locali.
printer()
# Ora, proviamo a chiamare questa funzione.
# Eseguiamo questa funzione

print_msg("Hello")Possiamo vedere che la funzione annidata printer() può accedere ai variabili non locali della funzione chiusa.

msg

Definire la funzione chiusura

Cosa succede se l'ultima riga della funzione print_msg() restituisce la funzione printer() invece di chiamarla? Questo significa che la definizione della funzione è come segue.
def print_msg(msg):
    # Questo è la funzione chiusa esterna
def printer():
        # Questo è la funzione annidata
    print(msg)
return printer  # Questo è cambiato
# Ora, proviamo a chiamare questa funzione.
# Output: Hello
another = print_msg("Hello")

another()

Questo è abbastanza inusuale.La funzione print_msg() è chiamata con una stringa, la funzione restituita da "Hello" è associata aUn altro

Nome. Quando si chiama another(), anche se abbiamo completato l'esecuzione della funzione print_msg(), ricordiamo il messaggio.In Python, questa tecnica di aggiungere alcuni dati ("Hello") al codicechiamatoChiusura.

Anche se la variabile è fuori portata o la funzione stessa è stata eliminata dal namespace corrente, ricorda questo valore nel contesto chiuso.

Prova a eseguire i seguenti comandi nel Python Shell per visualizzare l'output.

>>> del print_msg
>>> another()
Hello
>>> print_msg("Hello")
Traceback (chiamata più recente in fondo):
...
NameError: il nome 'print_msg' non è definito

Condizioni della chiusura?

Dal precedente esempio, è chiaro che in Python, quando una funzione annidata riferisce a un valore nel suo contesto chiuso, abbiamo una chiusura.

I seguenti punti riassumono le condizioni che devono essere soddisfatte per creare una chiusura in Python.

  • Dobbiamo avere una funzione annidata (funzione all'interno di una funzione).

  • La funzione annidata deve riferirsi ai valori definiti nella funzione chiusa.

  • La funzione chiusa deve restituire la funzione annidata.

Quando utilizzare la chiusura?

Allora, a cosa serve la chiusura?

La chiusura può evitare l'uso di valori globali e fornire una forma di nascondimento dei dati. Può anche fornire una soluzione orientata agli oggetti per il problema.

Quando i metodi implementati in una classe sono pochi (la maggior parte delle volte è un metodo), la chiusura può fornire un'altra soluzione più elegante. Ma quando il numero di attributi e metodi aumenta, è meglio implementare una classe.

Questo è un esempio semplice, in cui la chiusura potrebbe essere più preferibile rispetto alla definizione di una classe e alla creazione di un oggetto.

def make_multiplier_of(n):
    def multiplier(x):
        return x * n
    return multiplier
# Moltiplicatore di 3
times3 = make_multiplier_of(3)
# Moltiplicatore di 5
times5 = make_multiplier_of(5)
# Output: 27
print(times3(9))
# Output: 15
print(times5(3))
# Output: 30
print(times5(times3(2)))

I decoratori di Python ancheÈ stato ampiamente utilizzato il chiusura.

Infine, è meglio notare che è possibile trovare i valori chiusi nella funzione di chiusura.

Tutti gli oggetti di funzione hanno un attributo __closure__, che restituisce una tupla di oggetti cella se è una funzione di chiusura.

>>> make_multiplier_of.__closure__
>>> times3.__closure__
(<cella at 0x0000000002D155B8: oggetto int at 0x000000001E39B6E0>,)

L'oggetto cella ha l'attributo di memorizzazione dei valori chiusi cell_contents.

>>> times3.__closure__[0].cell_contents
3
>>> times5.__closure__[0].cell_contents
5