Nie było dokładnej odpowiedzi dotyczącej czasu Python3, więc udzieliłem odpowiedzi tutaj. Większość tego, co tu opisano, szczegółowo opisano w 4.2.2 Rozdzielczość nazw dokumentacji Python 3.
Jak podano w innych odpowiedziach, istnieją 4 podstawowe zakresy, LEGB, dla lokalnego, zamkniętego, globalnego i wbudowanego. Oprócz nich istnieje specjalny zakres, ciało klasy , które nie obejmuje zakresu obejmującego metody zdefiniowane w klasie; wszelkie przypisania w ciele klasy powodują, że zmienna jest odtąd związana w ciele klasy.
Zwłaszcza brak instrukcji blokowej poza tym defi classtworzenie zmiennego zakresu. W Pythonie 2 obsługa list nie tworzy zakresu zmiennych, jednak w Pythonie 3 zmienna pętli w ramach list jest tworzona w nowym zakresie.
Aby zademonstrować osobliwości ciała klasowego
x = 0
class X(object):
y = x
x = x + 1 # x is now a variable
z = x
def method(self):
print(self.x) # -> 1
print(x) # -> 0, the global x
print(y) # -> NameError: global name 'y' is not defined
inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)
Zatem, inaczej niż w ciele funkcji, można ponownie przypisać zmienną do tej samej nazwy w ciele klasy, aby uzyskać zmienną klasy o tej samej nazwie; dalsze wyszukiwania tej nazwy rozstrzygają zamiast tego zmienną klasy.
Jedną z większych niespodzianek dla wielu nowych użytkowników Pythona jest to, że forpętla nie tworzy zakresu zmiennego. W Pythonie 2 wyrażenia listowe również nie tworzą zakresu (podczas gdy generatory i wyrażenia dyktują!). Zamiast tego przeciekają wartość w funkcji lub zasięgu globalnym:
>>> [ i for i in range(5) ]
>>> i
4
Wyjaśnienia mogą być używane jako sprytny (lub okropny, jeśli chcesz) sposób modyfikowania zmiennych w wyrażeniach lambda w Pythonie 2 - wyrażenie lambda tworzy zakres zmiennych, podobnie jak definstrukcja, ale w lambda żadne instrukcje nie są dozwolone. Przypisanie będące instrukcją w Pythonie oznacza, że żadne przypisania zmiennych w lambda nie są dozwolone, ale rozumienie listy jest wyrażeniem ...
To zachowanie zostało naprawione w Pythonie 3 - brak wyrażeń związanych ze zrozumieniem lub zmiennych wyciekających z generatorów.
Globalny naprawdę oznacza zakres modułu; głównym modułem Pythona jest __main__; wszystkie importowane moduły są dostępne poprzez sys.moduleszmienną; aby uzyskać dostęp do __main__jednego z nich sys.modules['__main__'], lub import __main__; dostęp do nich i przypisywanie atrybutów jest całkowicie do przyjęcia; pojawią się jako zmienne w globalnym zakresie modułu głównego.
Jeśli nazwa zostanie kiedykolwiek przypisana w bieżącym zakresie (z wyjątkiem zakresu klasy), zostanie uznana za należącą do tego zakresu, w przeciwnym razie zostanie uznana za należącą do dowolnego obejmującego zakresu, który przypisuje zmiennej (może nie zostać przypisana jeszcze, albo wcale), czy wreszcie zasięg globalny. Jeśli zmienna jest uważana za lokalną, ale nie jest jeszcze ustawiona lub została usunięta, odczyt wartości zmiennej spowoduje UnboundLocalError, co jest podklasą NameError.
x = 5
def foobar():
print(x) # causes UnboundLocalError!
x += 1 # because assignment here makes x a local variable within the function
# call the function
foobar()
Zakres może zadeklarować, że wyraźnie chce zmodyfikować zmienną globalną (zakres modułu) za pomocą słowa kluczowego global:
x = 5
def foobar():
global x
print(x)
x += 1
foobar() # -> 5
print(x) # -> 6
Jest to również możliwe, nawet jeśli został ukryty w zakresie:
x = 5
y = 13
def make_closure():
x = 42
y = 911
def func():
global x # sees the global value
print(x, y)
x += 1
return func
func = make_closure()
func() # -> 5 911
print(x, y) # -> 6 13
W Pythonie 2 nie ma łatwego sposobu na modyfikację wartości w otaczającym zakresie; zwykle jest to symulowane przez wartość zmienną, taką jak lista o długości 1:
def make_closure():
value = [0]
def get_next_value():
value[0] += 1
return value[0]
return get_next_value
get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2
Jednak w Pythonie 3 nonlocalprzychodzi na ratunek:
def make_closure():
value = 0
def get_next_value():
nonlocal value
value += 1
return value
return get_next_value
get_next = make_closure() # identical behavior to the previous example.
nonlocalDokumentacja mówi, że
Nazwy wymienione w instrukcji nielokalnej, w przeciwieństwie do tych wymienionych w instrukcji globalnej, muszą odnosić się do wcześniej istniejących powiązań w zakresie obejmującym (zakresu, w którym należy utworzyć nowe powiązanie, nie można jednoznacznie określić).
tzn. nonlocalzawsze odnosi się do najbardziej wewnętrznego zewnętrznego zakresu nieglobalnego, w którym nazwa została powiązana (tj. przypisana, w tym używana jako forzmienna docelowa, w withklauzuli lub jako parametr funkcji).
Każda zmienna, która nie jest uważana za lokalną dla bieżącego zakresu lub dowolnego obejmującego zakresu, jest zmienną globalną. Globalna nazwa znajduje się w globalnym słowniku modułu; jeśli nie zostanie znaleziony, globalny jest następnie sprawdzany z wbudowanego modułu; nazwa modułu została zmieniona z python 2 na python 3; tak było w Pythonie 2, __builtin__a teraz w Pythonie 3 builtins. Jeśli przypiszesz atrybut wbudowanemu modułowi, będzie on później widoczny dla dowolnego modułu jako czytelna zmienna globalna, chyba że moduł ten ocienia je własną zmienną globalną o tej samej nazwie.
Przydatny może być także odczyt wbudowanego modułu; załóżmy, że chcesz funkcji drukowania w stylu Pythona 3 w niektórych częściach pliku, ale inne części pliku nadal używają printinstrukcji. W Pythonie 2.6-2.7 można uzyskać funkcję Python 3 za printpomocą:
import __builtin__
print3 = __builtin__.__dict__['print']
from __future__ import print_functionFaktycznie nie importuje się printnigdzie funkcji w Pythonie 2 - zamiast po prostu wyłącza zasady analizowania na printrachunku w bieżącym module obsługi printjak każdy inny identyfikator zmiennej, a tym samym pozwalając printfunkcja być spojrzał w builtins.