Lekcja 11 składa się z trzech części A, B, C, które możesz wykonać w dowolnej kolejności.
W tej lekcji wyjaśnimy pojęcie zakresu zmiennej. Główną ideą to, że mogą istnieć dwie różne zmienne o tej samej nazwie, gdy mają różne zakresy. To znacznie ułatwia pisanie i edytowanie programów, zwłaszcza dużych. Będzie to również niezbędnym elementem w późniejszym temacie, rekursji
Przykład zakresu zmiennej
W tym przykładzie część naszego programu będzie następująca:
def square(x): value = x * x return valueJest to funkcja, która oblicza kwadrat liczby
x
, na przykład square(5)
zwraca 25
. Załóżmy, że użyjemy nazwy square
w innej części programu, która również wykorzystuje wartości
zmiennej do innego celu:
# główne ciało programu zaczyna się tutaj value = 17 fivesquared = square(5) print(fivesquared, value)Pytanie brzmi, co zostanie wydrukowane w tym scenariuszu? Jeśli nie wiemy jak działa Python, to widzimy dwie możliwości:
- Jedną z możliwości jest to, że Python uzna, że obie
wartości
zmiennych w jakiś sposób powinny być "zachowane oddzielnie". Tak więc wywołaniesquare
zwróci 25, alewartość
w głównym ciele będzie nadal wynosić 17 i na wyjściu otrzymamy25
17
. - Inna możliwość może być następująca, gdy wykonywany jest
square
, istniejąca wartość zmiennej zostanie nadpisana wartością 25 i na wyjściu otrzymamy 25 25.
Zobaczmy, co właściwie się stanie!
Widzimy, że zachowanie Pythona jest zgodne z wariantem #1. W rzeczywistości, za każdym razem, gdy funkcja jest wywoływana, nie można wpłynąć na żadną zmienną zdefiniowaną poza tą funkcją. Wszelkie instrukcje przypisujące wartości zmiennym mają wpływ tylko na "lokalną" zmienną, która jest "wewnątrz" wywoływanej funkcji. Powód, dla którego Python i większość innych języków działają w ten sposób, sprawiają, że dużo prostsze jest napisanie długich programów z wieloma funkcjami. W szczególności, kiedy definiujemy nową funkcję, zawsze możemy używać dowolnych nazw zmiennych wewnątrz funkcji (w tym takich, jak result,
temp
i i
), nawet jeśli są one używane gdzie indziej w innych celach.
Aby zobaczyć to szczegółowo, spójrz na "Krok 6 z 8" w wizualizatorze. Zauważ, że istnieją dwie różne zmienne wartości:
jedna wewnątrz funkcji square
i jedna na zewnątrz (w obszarze "globalnym").
x = "outer"
def xReplace(value):
x = value
xReplace("inner")
print(x)
x = value
wpływa tylko na lokalną wersję zmiennej x
wewnątrz funkcji. Globalna wersja x
nie zmienia się. (Więc funkcja xReplace
jest bezużyteczna i nigdy nie daje żadnego efektu.)Inną, podobną koncepcją do zakresu jest przestrzeń nazw; Przestrzeń nazw jest jak zakres pakietu. Tak więc, jeśli nawet zaimportujesz
pakiet (np. math
), w którym użyto nazwy zmiennej x
, nie pokrywają się one ze zmienną x
używaną przez program, ponieważ leżą w różnych przestrzeniach nazw.
Patrząc na Zewnątrz
Są sytuacje, w których chcemy zmieszać zmienne z zakresu lokalnego i globalnego. Na przykład, mamy pewną zmienną zainicjowaną na początku programu, ale chcemy, aby nasze wywoływane funkcje były w stanie odczytać tą zmienną.
Tutaj, zakres lokalny nie zawierał zmiennej o nazwie favouriteTopping
, ale nie spowodowało to błędu. Reguła Pythona do sprawdzania zmiennych polega na tym, że jeśli sprawdzana zmienna nie istnieje w zasięgu lokalnym, to szukana jest w zasięgu globalnym. W naszym przypadku, rzeczywiście, favouriteTopping
została znaleziona w zasięgu globalnym. (W bardziej ogólnym przypadku, gdy jedna funkcja ciała wywołuje inną funkcję, mamy trzy zakresy: Python zawsze najpierw sprawdza zakres "najbardziej lokalny" i przechodzi krok po kroku do zakresu globalnego, dopóki nie zostanie znaleziona zmienna).
Dwa z powyższych przykładów, z orderPizzas i xReplace są pod względem składniowym niemal identyczne. Dlaczego Python tworzy nową lokalną zmienną x w xReplace , ale nie ma nowego favouriteTopping w orderPizzas ? Reguła Pythona jest następująca: jeśli tylko czytasz zmienną, to nie tworzona jest żadna nowa lokalna zmienna; ale jeśli zapisujesz do zmiennej, choćby tylko raz, to zmienna jest traktowana jako lokalna w ciele funkcji. (Jest to najczęstsza przyczyna UnboundLocalError : zobacz te dwa pytania [1, 2] w oficjalnej dokumentacji Pythona.) |
Argumenty funkcji są zawsze traktowane jako nowe lokalne zmienne, jak pokazano poniżej we fragmencie kodu (próbuje zresetować zmienną g
do 0
, ale nie powiedzie się).
Zmiany global
Podobnie jak wiele innych rzeczy, normalna procedura działa, jak opisano powyżej, dla 99% wszystkich sytuacji. Ale dla 1% nie, a ty może naprawdę chcesz zmienić zmienną globalną z poziomu funkcji. Python zawsze pozwala to zrobić z użyciem instrukcji global
.
Oto modyfikacja wcześniejszego przykładu xReplace
; deklarowanie w funkcji zmiennej jako global
umożliwia zmianę wartości globalnej z poziomu tej funkcji.
Jak wspomniano wcześniej, odczytywanie globalnej zmiennej nie wymaga użycia instrukcji global
; tylko zapisywanie. To wniosek z tej lekcji!