Come utilizzare le funzioni nidificate in Python

Come utilizzare le funzioni nidificate in Python
Questo articolo coprirà una guida sull'uso delle funzioni nidificate in Python. Le funzioni nidificate o le funzioni interne sono definite all'interno di altre funzioni di Python. Sono utili in alcuni schemi di programmazione e casi d'uso. Alcuni di loro saranno spiegati in questo articolo. Tutti i campioni di codice in questo articolo sono testati con Python 3.9.5 su Ubuntu 21.04.

Sulle funzioni nidificate / interne

Le funzioni nidificate, come suggerisce il nome, sono funzioni di Python create all'interno di altre funzioni di Python. Oltre al proprio ambito, la funzione interiore ha accesso agli oggetti disponibili nell'ambito della funzione esterna. La funzione interiore può essere definita come un singolo oggetto Python con i propri dati e variabili. Questa funzione interna è protetta dalla funzione esterna e non può essere chiamata o indicata dall'ambito globale. In questo modo la funzione interiore funge da entità nascosta che funziona solo all'interno dei confini della funzione esterna e l'ambito globale rimane inconsapevole. Questo processo è anche noto come "incapsulamento" nella programmazione. Ecco un esempio di una funzione nidificata in Python.

def visibile_outer_function (nome):
def hidden_inner_function ():
Stampa (nome)
Hidden_inner_function ()
VisiBile_OUTER_Function ("John")
Hidden_inner_function ()

La funzione esterna prende un argomento obbligatorio chiamato "nome". La funzione interna ha accesso all'ambito della funzione esterna in modo che possa utilizzare la variabile del nome. Una chiamata alla funzione interna viene quindi effettuata nella funzione esterna. Successivamente, una chiamata a funzioni sia interiori che esterne viene fatta nell'ambito globale. Dopo aver eseguito il campione di codice sopra, è necessario ottenere il seguente output:

John
Traceback (chiamata più recente per ultima):
File "Main.py ", riga 9, in
Hidden_inner_function ()
NameError: il nome 'Hidden_inner_function' non è definito

Come puoi vedere nell'output, la funzione esterna funziona bene quando la chiami dall'ambito globale. Viene lanciato un errore quando si tenta di chiamare la funzione interiore in quanto non è disponibile una cosa disponibile nell'ambito globale.

Funzioni interne Usa i casi

Ora che hai una certa comprensione delle funzioni nidificate, potresti chiederti della loro utilità e quando usarle. Uno degli usi più comuni delle funzioni interne è per la creazione di funzioni di supporto all'interno della funzione principale. Le funzioni interne possono anche essere utilizzate come decoratori e possono essere utilizzate per implementare le chiusure nel programma. Questi casi d'uso sono spiegati di seguito con esempi.

Creazione di una funzione di supporto

Le funzioni di supporto sono come qualsiasi altra funzione di Python, ma sono chiamate funzioni "helper" perché possono aiutare a organizzare meglio un codice complesso e possono essere riutilizzati in qualsiasi numero di volte per evitare la ripetizione del codice. Di seguito è riportato un campione di codice che illustra una funzione di supporto interno.

def get_ticket_price (nome):
Membri = ["Tony", "Peter", "Mark"]
Prezzo = 10
def get_discoted_price (sconto = 1.0):
restituzione (prezzo * sconto)
Se il nome nei membri:
ticket_price = get_discounted_price (sconto = 0.50)
altro:
ticket_price = get_discounted_price ()
print ("prezzo del biglietto per" + nome + "è: $" + str (ticket_price))
get_ticket_price ("Tony")
get_ticket_price ("John")

La principale funzione esterna richiamabile è "get_ticket_price". Prende il nome di una persona come argomento obbligatorio. La funzione "get_discounted_price" è una funzione aiutante interiore che prende "sconto" come argomento opzionale. L'elenco "membri" contiene nomi di tutti i membri registrati che hanno diritto a uno sconto. Un prezzo scontato per i membri viene calcolato chiamando la funzione interiore e fornendo un valore di sconto come argomento. Questa funzione helper può essere chiamata più volte in base ai requisiti e puoi anche modificare la logica all'interno della funzione interna. Pertanto le funzioni di aiutante interiore consentono di semplificare il codice ed evitare una ripetizione inutile. Dopo aver eseguito il campione di codice sopra, è necessario ottenere il seguente output:

Il prezzo del biglietto per Tony è: $ 5.0
Il prezzo del biglietto per John è: $ 10.0

Come puoi vedere nell'output sopra, Tony ottiene uno sconto sul prezzo del biglietto come è nella lista dei membri.

Implementazione di chiusure

Le chiusure sono istanze di funzioni interne che vengono restituite da funzioni esterne. Queste funzioni interne hanno accesso all'ambito delle funzioni esterne e continuano ad avere accesso all'ambito della funzione esterna anche dopo che la funzione esterna ha smesso di eseguire. Dai un'occhiata al campione del codice di seguito:

def get_discoted_price (prezzo):
def scontated_price (sconto):
Prezzo di rendimento * sconto
restituire scontate_price
First_Discount = get_discounted_price (10)
Second_Discount = get_discounted_price (10)
Stampa (First_Discount (0.50))
Stampa (Second_Discount (0.60))

La funzione esterna "get_discounted_price" restituisce un riferimento alla funzione interna chiamata "scontate_price". Si noti che nell'istruzione di ritorno, la funzione viene chiamata senza parentesi graffe. Successivamente, due nuove istanze chiamate "First_Discount" e "Second_Dicount" vengono create chiamando la funzione esterna e un argomento "prezzo" viene fornito a queste chiamate. In questo momento, la funzione esterna ha terminato l'esecuzione, ma il suo stato è stato salvato negli oggetti First_Discount e Second_Discount. Ora, quando chiami le istanze First_Discount e Second_Discount con parentesi graffe e argomenti, avranno già accesso a una variabile chiamata Price insieme al suo valore. L'argomento fornito a questi casi ora va alla funzione interna che poi restituisce un risultato.

Dopo aver eseguito il campione di codice sopra, è necessario ottenere il seguente output:

5.0
6.0

Le chiusure sono generalmente utilizzate in situazioni in cui il programma richiede di preservare lo stato di una funzione.

Creazione di funzioni di decorazione

Il decoratore funziona in Python Modifica il comportamento di una funzione Python esistente senza cambiarla. Quindi, quando si collega un decoratore a una funzione, è possibile aggiungere ulteriori funzionalità alla funzione o modificarne il comportamento mantenendo intatto il suo comportamento originale. Un tipico decoratore di Python sembra questo:

@decoratore
decorato ():
passaggio

Qui "@Decorator" modificherà il comportamento della funzione "decorata". È possibile creare funzioni del decoratore utilizzando funzioni nidificate. Per creare un decoratore, definire una funzione e passare a una funzione esterna come argomento. Questa funzione passata viene quindi chiamata all'interno di un'altra funzione interna in cui è possibile utilizzarla e implementare la logica. Infine la funzione esterna restituisce la funzione interna che contiene il comportamento modificato. Dai un'occhiata al campione di codice qui sotto.

def get_discoted_price (importo):
def scontated_price ():
prezzo = importo ()
new_price = prezzo * 0.50
Restituisce New_Price
restituire scontate_price

La funzione esterna "get_discounted_price" viene passata un'altra funzione chiamata "importo" come argomento. La funzione interna utilizza la funzione passata e aggiunge un certo comportamento ad essa. La funzione esterna restituisce quindi un riferimento alla funzione interna che contiene il comportamento modificato. Dopo aver definito il decoratore, puoi chiamarlo nel modo seguente:

@get_discounted_price
def get_price ():
restituzione 10
print (get_price ())

I decoratori sono attaccati a funzioni il cui comportamento stai cercando di modificare. Iniziano sempre con il simbolo "@". Usando il decoratore qui, stai passando la funzione "get_price" alla funzione "get_discounted_price" come argomento. Ora quando chiami la funzione GET_PRICE, non otterrai 10 come output ma un numero modificato dal decoratore GET_Discounted_Price. Dopo aver eseguito il campione di codice sopra, è necessario ottenere il seguente output:

5.0

L'utilizzo del decoratore mostrato sopra è equivalente al seguente codice:

def get_discoted_price (importo):
def scontated_price ():
prezzo = importo ()
new_price = prezzo * 0.50
Restituisce New_Price
restituire scontate_price
def get_price ():
restituzione 10
FINAL_PRICE = GET_DISCOUNTED_PRICE (GET_PRICE)
print (final_price ())

Invece di usare una sintassi "@decorator" come stenografia, puoi semplicemente creare una nuova istanza della funzione esterna e fornirla un'altra funzione come argomento. Il risultato finale di entrambi i modelli di codifica è lo stesso. Poiché i decoratori mantengono intatto il comportamento della funzione originale, sono davvero utili se si desidera chiamarli caso per caso e allo stesso tempo preservare l'implementazione della vaniglia di una funzione decorata.

Conclusione

È possibile utilizzare le funzioni nidificate in vari modi per creare funzioni interne che aggiungono ulteriori funzionalità e logica alla funzione esterna. Alcuni dei casi d'uso più comuni per le funzioni nidificate sono stati spiegati nell'articolo. Puoi anche creare le tue implementazioni di funzioni interne, poiché tutte le funzioni sono trattate come oggetti di prima classe in Python e possono essere restituiti o superati come argomenti.