Zanurkuj w Pythonie/locals i globals: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
koniec tłumaczenia |
Nie podano opisu zmian |
||
Linia 3:
== <tt>locals</tt> i <tt>globals</tt> ==
Odejdźmy teraz na minutkę od przetwarzania HTML-
Pamiętasz <tt>locals</tt>? Pierwszy raz zobaczyłeś
def unknown_starttag(self, tag, attrs):
strattrs = "".join([' %s="%s"' % (key, value) for key, value in attrs])
self.pieces.append("<%(tag)s%(strattrs)s>" % locals())
Nie, czekaj, nie
Python korzysta z czegoś, co się nazywa przestrzenią nazw (ang. ''namespace''), aby śledzić zmienne. Przestrzeń nazw jest
Z dowolnego miejsca Pythonowego programu mamy dostęp do kliku przestrzeni nazw. Każda funkcja posiada własną przestrzeń nazw, nazywaną ''lokalną przestrzenią nazw'', a która śledzi zmienne funkcji, włączając w to jej argumenty i lokalnie zdefiniowane zmienne. Każdy moduł posiada własną przestrzeń nazw, nazwaną ''globalną przestrzenią nazw'', a która śledzi zmienne modułu, włączając w to funkcje, klasy i inne zaimportowane moduły, a także zmienne zdefiniowane w tym module i stałe. Jest także wbudowana przestrzeń nazw, dostępna z każdego modułu, a która przechowuje funkcje wbudowane i wyjątki.
Kiedy pewna linia kodu pyta się o wartość zmiennej <tt>x</tt>, Python przeszuka wszystkie przestrzenie nazw, aby znaleść ją, w poniższym porządku:
Linia 21:
# wbudowana przestrzeń nazw namespace - globalna dla wszystkich modułów. Ponieważ jest to ostatnia deska ratunku, Python przyjmie, że <tt>x</tt> jest nazwą wbudowanej funkcji lub zmiennej.
Jeśli Python nie znajdzie <tt>x</tt> w żadnej z tych przestrzeni nazw, poddaje się i
{{Uwaga|
Python 2.2 wprowadził subtelną, a zarazem ważną zmianę,
}}
Zmieszałeś się? Nie panikuj! Jest to naprawdę cool. Podobnie, jak wiele rzeczy w Pythonie, przestrzenie nazw są bezpośrednio dostępne podczas wykonywania programu. Jak? Do lokalnej przestrzeni nazw mamy dostęp poprzez wbudowaną funkcję <tt>locals</tt>, a
'''Przykład 8.10. Wprowadzenie do <tt>locals</tt>'''
Linia 41:
# Funkcja <tt>foo</tt> posiada dwie zmienne w swojej lokalnej przestrzeni nazw: <tt>arg</tt>, której wartość jest przekazana do funkcji, a także <tt>x</tt>, która jest zdefiniowana wewnątrz funkcji.
# <tt>locals</tt> zwraca słownik par nazwa/wartość. Kluczami słownika są nazwy
# Pamiętaj, Python jest dynamicznie typowany, dlatego też możemy w prosty sposób jako argument <tt>arg</tt>, przekazać napis. Funkcja (a także wywołanie <tt>locals</tt>) będą nadal działać jak należy. <tt>locals</tt> działa z wszystkimi zmiennymi dowolnych typów danych.
Linia 56:
print k, "=", v
#
Teraz, uruchamiając skrypt z linii poleceń otrzymamy takie wyjście (twoje wyjście może się nieco różnić, zależnie od tego, na jakim systemie i gdzie zainstalowałeś Pythona):
Linia 70:
# <tt>SGMLParser</tt> został zaimportowany z <tt>sgmllib</tt>, wykorzystując <tt>from module import</tt>. Oznacza to, że został zaimportowany bezpośrednio do przestrzeni nazw modułu i w tym też miejscu jest.
# W przeciwieństwie do <tt>SGMLParser</tt>-a, <tt>htmlentitydefs</tt> został zaimportowany wykorzystując instrukcję <tt>import</tt>. Oznacza to, że moduł <tt>htmlentitydefs</tt> sam w sobie jest przestrzenią nazw, ale zmienna <tt>entitydefs</tt> wewnątrz <tt>htmlentitydefs</tt> już nie.
# Moduł ten definiuje jedną klasę, <tt>BaseHTMLProcessor</tt> i
# Pamiętasz trik <tt>if __name__</tt>? Kiedy uruchamiamy moduł (zamiast importować go z innego modułu), to wbudowany atrybut <tt>__name__</tt> ma specjalną wartość, <tt>"__main__"</tt>. Ponieważ uruchomiliśmy ten moduł jako skrypt z linii poleceń, wartość <tt>__name__</tt> wynosi <tt>"__main__"</tt>, dlatego też zostanie wykonany mały kod testowy, który wypisuje <tt>globals</tt>.
{{Infobox|
}}
Tutaj mamy inną ważną różnicę między funkcjami <tt>locals</tt> i <tt>globals</tt>, a o
'''Przykład 8.12. <tt>locals</tt> jest tylko do odczytu, a <tt>globals</tt> już nie'''
Linia 97:
# <tt>locals</tt> jest funkcją zwracającą słownik i w tym miejscu zmieniamy wartość w tym słowniku. Możesz myśleć, że wartość zmiennej <tt>x</tt> zostanie zmieniona na <tt>2</tt>, jednak tak nie jest. <tt>locals</tt> właściwie nie zwraca lokalnej przestrzeni nazw, zwraca jego kopię. Zatem zmieniając ją, nie zmieniamy wartości zmiennych w lokalnej przestrzeni nazw.
# Zostanie wypisane <tt>x= 1</tt>, a nie <tt>x= 2</tt>.
# Po tym, jak zostaliśmy poparzeni przez <tt>locals</tt>, możemy myśleć, że ta operacja nie zmieni wartości <tt>z</tt>, ale w rzeczywistości zmieni
# Wypisze <tt>z= 8</tt>, a nie <tt>z= 7</tt>.
|