Python Closures: Jak jej používat a proč?

V tomto kurzu se dozvíte o uzavření Pythonu, o tom, jak definovat uzavření, a o důvodech, proč byste jej měli používat.

Nonlocal proměnná ve vnořené funkci

Než se dostaneme k závěru, musíme nejprve pochopit, co je vnořená funkce a nelokální proměnná.

Funkce definovaná uvnitř jiné funkce se nazývá vnořená funkce. Vnořené funkce mohou přistupovat k proměnným v uzavřeném oboru.

V Pythonu jsou tyto nelokální proměnné ve výchozím nastavení jen pro čtení a musíme je explicitně deklarovat jako nelokální (pomocí nelokálního klíčového slova), abychom je mohli upravit.

Následuje příklad vnořené funkce přistupující k nelokální proměnné.

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) printer() # We execute the function # Output: Hello print_msg("Hello")

Výstup

 Ahoj

Vidíme, že vnořená printer()funkce dokázala přistupovat k nelokální proměnné zprávy obklopující funkce.

Definování funkce uzavření

Ve výše uvedeném příkladu, co by se stalo, kdyby poslední řádek funkce print_msg()vrátil printer()funkci namísto jejího volání? To znamená, že funkce byla definována takto:

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) return printer # returns the nested function # Now let's try calling this function. # Output: Hello another = print_msg("Hello") another()

Výstup

 Ahoj

To je neobvyklé.

print_msg()Funkce byla volána s řetězcem "Hello"a vrací funkce byla vázána na jméno jiné. Při volání another()byla zpráva stále zapamatována, i když jsme již dokončili provádění print_msg()funkce.

Tato technika, pomocí které se některá data ( "Hellov tomto případě) připojí ke kódu, se v Pythonu nazývá uzavření .

Tato hodnota v uzavírajícím oboru je zapamatována, i když proměnná zmizí z rozsahu nebo je samotná funkce odebrána z aktuálního oboru názvů.

Zkuste spustit následující v prostředí Pythonu, abyste viděli výstup.

 >>> del print_msg >>> another() Hello >>> print_msg("Hello") Traceback (most recent call last):… NameError: name 'print_msg' is not defined

Zde vrácená funkce stále funguje, i když byla odstraněna původní funkce.

Kdy máme uzávěry?

Jak je patrné z výše uvedeného příkladu, v Pythonu máme uzávěr, když vnořená funkce odkazuje na hodnotu ve svém uzavřeném rozsahu.

Kritéria, která musí být splněna pro vytvoření uzavření v Pythonu, jsou shrnuta v následujících bodech.

  • Musíme mít vnořenou funkci (funkci uvnitř funkce).
  • Vnořená funkce musí odkazovat na hodnotu definovanou v uzavírající funkci.
  • Uzavírací funkce musí vrátit vnořenou funkci.

Kdy použít uzávěry?

K čemu jsou tedy uzávěry dobré?

Uzávěry se mohou vyhnout použití globálních hodnot a poskytují určitou formu skrývání dat. Může také poskytnout objektově orientované řešení problému.

Pokud je ve třídě implementováno několik metod (ve většině případů jedna metoda), uzávěry mohou poskytnout alternativní a elegantnější řešení. Ale když se počet atributů a metod zvětší, je lepší implementovat třídu.

Zde je jednoduchý příklad, kdy by uzavření mohlo být výhodnější než definování třídy a vytváření objektů. Ale preference jsou všechny vaše.

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

Výstup

 27 15 30

Pythonové dekoratéři také hojně využívají uzávěry.

Na závěr je dobré poukázat na to, že lze zjistit hodnoty, které jsou uzavřeny ve funkci uzavření.

Všechny funkční objekty mají __closure__atribut, který vrací n-tici buněčných objektů, pokud se jedná o uzavírací funkci. S odkazem na výše uvedený příklad známe times3a times5jedná se o uzavírací funkce.

 >>> make_multiplier_of.__closure__ >>> times3.__closure__ (,)

Objekt buňky má atribut cell_contents, který ukládá uzavřenou hodnotu.

 >>> times3.__closure__(0).cell_contents 3 >>> times5.__closure__(0).cell_contents 5

Zajímavé články...