myList = [5, 2]
def foo():
myList[0] = 6
W powyższym przykładzie myList
jest wciąż zmutowany, chociaż nie jest globalny i nie jest przekazywany przez parametr. Nie działa to jednak, jeśli zmienna nie jest listą.
Odpowiedzi:
2 dla odpowiedzi № 1Zasady zasięgu są mniej więcej takie:
- Zakres lokalny: definiujesz zmienną wewnątrz funkcji
- Osiąganie zasięgu: twoja funkcja znajduje się wewnątrz innej funkcji (lub wielu warstw funkcji), a jedna z wyższych (otaczających) funkcji zadeklarowała zmienną
- Zakres globalny: zasięg globalny (moduł lub plik)
- Wbudowany: Dowolne wbudowane wartości natywne dla Pythona
Jest to znane jako reguła LEGB.
W twoim przypadku dzieje się tak dlatego, że nie przypisujesz wartości do nazwy myList
wnętrze foo()
. Przypisujesz tylko wartość 0
indeks istniejącej listy. Dlatego globalna wartość myList
jest zasięg, z którego korzystasz.
2 dla odpowiedzi nr 2
myList
jest jednak zmienną globalną. Istnieje w kontekście foo
, gdzie uzyskujesz dostęp i modyfikujesz jeden z jego elementów.
myList = [0, 5]
def foo():
myList[0] = 6
print("Before foo: {}".format(myList))
foo()
print("After foo: {}".format(myList))
Wydajność
Before foo: [0, 5]
After foo: [6, 5]
Nie działa to jednak, jeśli zmienna nie jest listą.
Zakładam, że próbowałeś czegoś podobnego do następującego:
a = 0
def bar():
a = 6
print("Before bar: {}".format(a))
bar()
print("After bar: {}".format(a))
Wydajność
Before bar: 0
After bar: 0
W takim przypadku nie zaobserwujesz żadnych zmian w pliku światowy zmienna a
ponieważ wewnątrz bar
przypisujesz do nowa zmienna lokalna a
który cienie zmienna globalna o tej samej nazwie. Ustawiłeś zmienna lokalna a
do 6, co nie ma wpływu, ponieważ zmienna jest odrzucana, gdy tylko funkcja się kończy.
Możesz pokazać, że deklarowane są nawet proste liczby całkowitew zasięgu globalnym można uzyskać dostęp w zakresach funkcji, wykonując coś podobnego do następującego. W tym przypadku określamy, że funkcja powinna modyfikować istniejącą zmienną globalną b
zamiast przypisywać nowy lokalny.
b = 0
def baz():
global b
b = 6
print("Before baz: {}".format(b))
baz()
print("After baz: {}".format(b))
Wydajność
Before baz: 0
After baz: 6