Jak używać funkcji zagnieżdżonych w Pythonie

Jak używać funkcji zagnieżdżonych w Pythonie
W tym artykule obejmie przewodnik o korzystaniu z funkcji zagnieżdżonych w Pythonie. Funkcje zagnieżdżone lub funkcje wewnętrzne są zdefiniowane w innych funkcjach Pythona. Są one przydatne w niektórych wzorach programowania i przypadkach użycia. Niektóre z nich zostaną wyjaśnione w tym artykule. Wszystkie próbki kodu w tym artykule są testowane z Python 3.9.5 na Ubuntu 21.04.

O funkcjach zagnieżdżonych / wewnętrznych

Funkcje zagnieżdżone, jak sama nazwa wskazuje, to funkcje Pythona, które są tworzone w innych funkcjach Pythona. Oprócz własnego zakresu funkcja wewnętrzna ma dostęp do obiektów dostępnych w zakresie funkcji zewnętrznej. Funkcję wewnętrzną można nazwać pojedynczym obiektem Python z własnymi danymi i zmiennymi. Ta wewnętrzna funkcja jest chroniona przez funkcję zewnętrzną i nie można jej wywołać ani odnieść z zakresu globalnego. W ten sposób funkcja wewnętrzna działa jako ukryty byt, który działa tylko w granicach funkcji zewnętrznej, a globalny zakres pozostaje jej nieświadomy. Proces ten jest również znany jako „enkapsulacja” w programowaniu. Oto przykład zagnieżdżonej funkcji w Pythonie.

def visibile_outer_function (nazwa):
def hidden_inner_function ():
Nazwa wydruku)
hidden_inner_function ()
Visibile_Outer_function („John”)
hidden_inner_function ()

Funkcja zewnętrzna przyjmuje jeden obowiązkowy argument o nazwie „Nazwa”. Funkcja wewnętrzna ma dostęp do zakresu funkcji zewnętrznej, aby mogła skorzystać z zmiennej nazwy. Wezwanie do funkcji wewnętrznej jest następnie wykonywane w funkcji zewnętrznej. Następnie w globalnym zakresie odbywa się zarówno funkcje wewnętrzne, jak i zewnętrzne. Po uruchomieniu powyższej próbki kodu należy uzyskać następujące dane wyjściowe:

Jan
Traceback (najnowsze połączenie ostatnie):
Plik ”główny.py ", linia 9, w
hidden_inner_function ()
NameError: Nazwa „Hidden_inner_function” nie jest zdefiniowana

Jak widać na wyjściu, funkcja zewnętrzna działa dobrze, gdy wywołujesz ją z globalnego zakresu. Błąd pojawia się, gdy próbujesz wywołać funkcję wewnętrzną, ponieważ nie jest dostępna w zakresie globalnego.

Funkcje wewnętrzne przypadki użycia

Teraz, gdy masz pewne zrozumienie funkcji zagnieżdżonych, możesz zastanawiać się nad ich użytecznością i kiedy z nich korzystać. Jednym z najczęstszych zastosowań funkcji wewnętrznych jest tworzenie funkcji pomocniczych w funkcji głównej. Funkcje wewnętrzne mogą być również używane jako dekoratorzy i mogą być używane do wdrażania zamknięć w programie. Te przypadki użycia wyjaśniono poniżej z przykładami.

Tworzenie funkcji pomocnika

Funkcje pomocnicze są jak każde inne funkcje Pythona, ale nazywane są funkcjami „pomocniczymi”, ponieważ mogą pomóc w lepszym zorganizowaniu złożonego kodu i mogą być ponownie wykorzystywane w dowolnym momencie, aby uniknąć powtarzania kodu. Poniżej znajduje się próbka kodu, która ilustruje funkcję pomocnika wewnętrznego.

def get_ticket_price (nazwa):
członkowie = [„Tony”, „Peter”, „Mark”]
Cena = 10
def get_discounted_price (rabat = 1.0):
zwrot (cena * rabat)
Jeśli nazwa w członkach:
bilet_price = get_discounted_price (rabat = 0.50)
w przeciwnym razie:
bilet_price = get_discounted_price ()
Drukuj („Cena biletu dla„ + nazwa + ”to: $" + str (Ticket_Price))
get_ticket_price („Tony”)
get_ticket_price („John”)

Główną funkcją zewnętrzną, którą można nazwać, jest „get_ticket_price”. To imienia osoby jako obowiązkowego argumentu. Funkcja „get_discounted_price” to funkcja pomocnika wewnętrznego, która wymaga „rabatu” jako opcjonalnego argumentu. Lista „członków” zawiera nazwiska wszystkich zarejestrowanych członków, którzy kwalifikują się do zniżki. Dyskontowana cena dla członków jest obliczana poprzez wywołanie funkcji wewnętrznej i dostarczając jej wartość rabatową jako argument. Ta funkcja pomocnika można nazwać wiele razy w oparciu o wymagania, a także możesz zmienić logikę w funkcji wewnętrznej. Zatem funkcje pomocnika wewnętrznego pozwalają uprościć kod i uniknąć niepotrzebnego powtórzenia. Po uruchomieniu powyższej próbki kodu należy uzyskać następujące dane wyjściowe:

Cena biletu dla Tony'ego wynosi: 5 USD.0
Cena biletu dla Johna to: 10 USD.0

Jak widać na powyższym wyjściu, Tony otrzymuje zniżkę na cenę biletu, ponieważ jest na liście członków.

Wdrażanie zamknięć

Zamknięcia to instancje funkcji wewnętrznych, które są zwracane przez funkcje zewnętrzne. Te wewnętrzne funkcje mają dostęp do zakresu funkcji zewnętrznych i nadal mają dostęp do zakresu funkcji zewnętrznej, nawet po tym, jak funkcja zewnętrzna przestała wykonywać. Spójrz na poniższą próbkę kodu:

def get_discounted_price (cena):
def Discounded_Price (zniżka):
Cena zwrotu * Rabat
Zwrot Disund_Price
First_discount = get_discounted_price (10)
second_discount = get_discounted_price (10)
wydrukuj (First_discount (0.50))
Drukuj (second_discount (0.60))

Funkcja zewnętrzna „get_discounted_price” zwraca odniesienie do funkcji wewnętrznej o nazwie „Discounted_Price”. Zauważ, że w instrukcji powrotnej funkcja jest wywoływana bez aparatu. Następnie tworzone są dwa nowe instancje o nazwie „First_discount” i „second_dicount”, wywołując funkcję zewnętrzną i do tych połączeń dostarczana jest wartość argumentu „ceny”. W tym momencie funkcja zewnętrzna zakończyła się wykonywanie, ale jej stan został zapisany w obiektach First_discount i Second_discount. Teraz, gdy wywołasz instancje pierwszego_discount i drugie_discount z aparatami ortodontyczny. Argument dostarczany w tych przypadkach trafia teraz do funkcji wewnętrznej, która następnie zwraca wynik.

Po uruchomieniu powyższej próbki kodu należy uzyskać następujące dane wyjściowe:

5.0
6.0

Zamknięcia są zwykle stosowane w sytuacjach, w których program wymaga zachowania stanu funkcji.

Tworzenie funkcji dekoracyjnych

Dekorator funkcjonuje w Python Modyfikuj zachowanie istniejącej funkcji Pythona bez jej zmiany. Więc kiedy przymocujesz dekoratora do funkcji, możesz dodać dodatkową funkcjonalność do funkcji lub zmodyfikować jej zachowanie, jednocześnie utrzymując nienaruszone oryginalne zachowanie. Typowy dekorator Python wygląda tak:

@dekorator
def dekorated ():
przechodzić

Tutaj „@Decorator” zmodyfikuje zachowanie funkcji „ozdobionej”. Możesz tworzyć funkcje dekoratora za pomocą funkcji zagnieżdżonych. Aby utworzyć dekoratora, zdefiniuj funkcję i przekazać ją do funkcji zewnętrznej jako argument. Ta przekazana funkcja jest następnie wywoływana w innej funkcji wewnętrznej, w której można ją użyć i zaimplementować logikę. Wreszcie funkcja zewnętrzna zwraca wewnętrzną funkcję, która zawiera zmodyfikowane zachowanie. Spójrz na poniższą próbkę kodu.

def get_discounted_price (kwota):
def Discounded_Price ():
cena = kwota ()
new_price = cena * 0.50
zwróć New_Price
Zwrot Disund_Price

Funkcja zewnętrzna „get_discounted_price” jest przekazywana inna funkcja o nazwie „kwota” jako argument. Funkcja wewnętrzna wykorzystuje przekazaną funkcję i dodaje do niej pewne zachowanie. Funkcja zewnętrzna zwraca następnie odniesienie do funkcji wewnętrznej, która zawiera zmodyfikowane zachowanie. Po zdefiniowaniu dekoratora możesz zadzwonić w następujący sposób:

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

Dekoratorzy są przywiązani do funkcji, których zachowanie próbujesz zmodyfikować. Zawsze zaczynają od symbolu „@”. Korzystając z dekoratora tutaj, przekazujesz funkcję „get_price” do funkcji „get_discounted_price” jako argument. Teraz, kiedy wywołasz funkcję get_price, nie otrzymasz 10 jako wyjściowe, ale liczba zmodyfikowana przez dekorator get_discounted_price. Po uruchomieniu powyższej próbki kodu należy uzyskać następujące dane wyjściowe:

5.0

Zastosowanie dekoratora pokazane powyżej jest równoważne z następującym kodem:

def get_discounted_price (kwota):
def Discounded_Price ():
cena = kwota ()
new_price = cena * 0.50
zwróć New_Price
Zwrot Disund_Price
def get_price ():
Zwrot 10
final_price = get_discounted_price (get_price)
print (final_price ())

Zamiast używać składni „@Decorator” jako stenografii, możesz po prostu utworzyć nową instancję funkcji zewnętrznej i dostarczyć inną funkcję jako argument. Wynik końcowy obu wzorów kodowania jest taki sam. Ponieważ dekoratorzy zachowują nienaruszone zachowanie oryginalnej funkcji, są one naprawdę przydatne, jeśli chcesz je nazwać w poszczególnych przypadkach, a jednocześnie zachowaj waniliową implementację funkcji zdobionej.

Wniosek

Możesz użyć funkcji zagnieżdżonych na różne sposoby, aby tworzyć funkcje wewnętrzne, które dodają dodatkowej funkcjonalności i logiki do funkcji zewnętrznej. Niektóre z najczęstszych przypadków użycia funkcji zagnieżdżonych zostały wyjaśnione w artykule. Możesz także tworzyć własne implementacje funkcji wewnętrznych, ponieważ wszystkie funkcje są traktowane jako obiekty pierwszej klasy w Python i można je zwrócić lub przekazać jako argumenty.