CodeGym /Kursy /Python SELF PL /Zakresy widoczności zmiennych

Zakresy widoczności zmiennych

Python SELF PL
Poziom 6 , Lekcja 4
Dostępny

10.1 Lokalne zmienne funkcji

W Pythonie zmienna jest dostępna (można się do niej odwoływać) od momentu jej utworzenia aż do końca swojego zakresu widoczności — najczęściej jest to funkcja, w której została zadeklarowana. Jeśli zmienna została zadeklarowana poza wszystkimi funkcjami, to nazywana jest globalną.

W Pythonie zakresy widoczności zmiennych określają kontekst, w którym zmienne są dostępne do użycia. Zakresy widoczności pomagają unikać konfliktów nazw i zarządzać dostępem do danych. Główne typy zakresów widoczności w Pythonie obejmują:

Lokalny zakres widoczności: Zmienne utworzone wewnątrz funkcji istnieją w lokalnym zakresie widoczności tej funkcji i są dostępne tylko wewnątrz niej.

Zakres widoczności funkcji zagnieżdżonych: Jeśli funkcja jest zdefiniowana wewnątrz innej funkcji, jej zmienne są dostępne tylko wewnątrz tej zagnieżdżonej funkcji.

Globalny zakres widoczności: Zmienne, zdefiniowane na poziomie skryptu lub modułu, są uważane za globalne i dostępne z każdej części kodu w tym samym module.

Wbudowany zakres widoczności: To specjalny zakres widoczności, który obejmuje wszystkie wbudowane obiekty i funkcje Pythona, dostępne domyślnie (na przykład print() i len()).

Zasada LEGB

Do rozwiązywania zmiennych Python używa zasady LEGB, która określa kolejność, w której interpreter szuka zmiennych:

  • L (Local) — Najpierw szuka w lokalnym zakresie widoczności.
  • E (Enclosed) — Następnie w zakresach widoczności wszystkich zagnieżdżonych funkcji, od najbliższej do zewnętrznej.
  • G (Global) — Dalej w globalnym zakresie widoczności.
  • B (Built-in) — Na koniec, w wbudowanym zakresie widoczności.

Przykłady użycia


x = "global"  # Zmienna globalna

def outer():
    y = "outer local"  # Zmienna lokalna zewnętrznej funkcji
    def inner():
        z = "inner local"  # Zmienna lokalna zagnieżdżonej funkcji
        print(x)  # Wyświetli "global"
        print(y)  # Wyświetli "outer local"
        print(z)  # Wyświetli "inner local"
    inner()

outer()

Zmienna z jest dostępna tylko wewnątrz funkcji inner().

Zmienna y jest dostępna wewnątrz funkcji outer() i we wszystkich funkcjach, zadeklarowanych wewnątrz niej.

Zmienna x jest dostępna wszędzie w bieżącym pliku (module).

10.2 Dostęp do globalnych zmiennych: global x

Ciekawą cechą języka Python jest to, że zmienne z zewnętrznych zakresów widoczności (w które zagnieżdżony jest bieżący zakres widoczności) można tylko odczytywać.

Przy próbie zapisania czegoś do zewnętrznej zmiennej zostanie utworzona lokalna zmienna o takiej samej nazwie, a dostęp do zewnętrznej zmiennej zostanie utracony.

Przykład:


x = 10

def change_global():
    print(x)  # To spowoduje błąd, bo x będzie uznawane za zmienną lokalną po przypisaniu
    x = 20  # Tutaj zostanie utworzona lokalna zmienna x
    print(x)  # Wyświetli 20 (odwołanie do lokalnej zmiennej x)
        
change_global()
print(x)  # Wyświetli 10

Ten przykład nie działa i spowoduje błąd UnboundLocalError, ponieważ interpreter Pythona najpierw widzi przypisanie x = 20 i uważa, że x jest zmienną lokalną. Jednak, gdy interpreter dotrze do linii print(x), nie znajduje lokalnej zmiennej x, ponieważ nie została jeszcze zdefiniowana.

Zostało to zrobione dla bezpieczeństwa, aby lokalne zmienne przypadkowo nie zmieniały globalnych.

Operator global

Jeśli musisz świadomie zmienić wartość globalnej zmiennej wewnątrz funkcji, możesz użyć operatora global. Ten operator pozwala wyraźnie wskazać, że zmiana powinna nastąpić w globalnej zmiennej, a nie w lokalnej.

Aby zmienić wartość globalnej zmiennej wewnątrz funkcji, musisz zadeklarować tę zmienną na początku funkcji za pomocą global. To daje funkcji dostęp do zapisu w zmiennej:


x = 10

def change_global():
    global x  # Deklarujemy x jako globalną zmienną
    print(x)  # Wyświetli 10 (odwołanie do globalnej zmiennej x)
    x = 20  # Tutaj przypisujemy nową wartość do globalnej zmiennej x
    print(x)  # Wyświetli 20 (odwołanie do globalnej zmiennej x)

change_global()
print(x)  # Wyświetli 20

Użycie operatora global pozwala uniknąć błędu i prawidłowo zarządzać globalnymi zmiennymi.

Globalne zmienne mogą uczynić program mniej przewidywalnym i trudniejszym do zrozumienia, ponieważ ich wartości mogą być zmieniane w dowolnym miejscu programu. Jest to szczególnie krytyczne, jeśli program jest duży i rozwijany przez zespół programistów.

Choć czasami użycie zmiennych globalnych jest nieuniknione, lepiej starać się minimalizować ich użycie. Zamiast globalnych zmiennych rozważ użycie parametrów funkcji, wartości zwracanych i klas do przechowywania stanu.

Użycie zmiennych globalnych może prowadzić do nieoczekiwanych efektów ubocznych, utrudniać debugowanie i testowanie kodu, a także obniżać jego ponowne wykorzystanie. Dlatego zaleca się ostrożne i ograniczone używanie zmiennych globalnych, tylko gdy jest to naprawdę konieczne.

10.3 Dostęp do zmiennych nie-lokalnych: nonlocal

Poza globalnymi i lokalnymi zmiennymi, w Pythonie istnieją zmienne z zakresów pośrednich. Na przykład, gdy funkcja jest zagnieżdżona w innej funkcji. Do pracy z takimi zmiennymi używany jest operator nonlocal.

Operator nonlocal pozwala na pracę z zmiennymi w zagnieżdżonych funkcjach, zmieniając ich wartości w najbliższym zakresie widoczności, z wyłączeniem zmiennych globalnych.

Operator nonlocal pomaga uniknąć tworzenia nowej lokalnej zmiennej w zagnieżdżonej funkcji, gdy konieczne jest zmienienie zmiennej zdefiniowanej w zewnętrznej funkcji. Bez użycia nonlocal zmiany dotyczą tylko lokalnej zmiennej wewnętrznej funkcji, nie wpływając na zmienną w zewnętrznej funkcji.

Przykład:


def outer():
    count = 0

    def inner():
        nonlocal count
        count += 1
        return count

    return inner

counter = outer()
print(counter())  # Wyświetli 1

Oto bardziej praktyczny przykład użycia nonlocal do stworzenia licznika:


def create_counter():
    count = 0
    
    def increment():
        nonlocal count
        count += 1
        return count
    
    return increment

counter = create_counter()
print(counter())  # Wyświetli 1
print(counter())  # Wyświetli 2
print(counter())  # Wyświetli 3

Ten przykład demonstruje, jak nonlocal może być użyty w rzeczywistych scenariuszach do stworzenia funkcji, która zachowuje swój stan między wywołaniami.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION