Jeśli mam następujący kod w Pythonie:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
Narzeka
NameError: global name 'bar' is not defined
Jak mogę uzyskać dostęp do zmiennej klasy / statycznej bar
w metodzie bah
?
python
oop
static-variables
Ross Rogers
źródło
źródło
Odpowiedzi:
Zamiast
bar
używaćself.bar
lubFoo.bar
. Przypisanie doFoo.bar
spowoduje utworzenie zmiennej statycznej, a przypisanie doself.bar
spowoduje utworzenie zmiennej instancji.źródło
Zdefiniuj metodę klasy:
Teraz, jeśli
bah()
ma to być metoda instancji (tj. Mieć dostęp do siebie), nadal możesz bezpośrednio uzyskać dostęp do zmiennej klasy.źródło
Jak w przypadku wszystkich dobrych przykładów, uprościliśmy to, co faktycznie próbujesz zrobić. To dobrze, ale warto zauważyć, że Python ma dużą elastyczność, jeśli chodzi o zmienne klas i instancji. To samo można powiedzieć o metodach. Aby uzyskać dobrą listę możliwości, polecam przeczytanie wprowadzenia do zajęć w nowym stylu Michaela Fötscha , zwłaszcza części od 2 do 6.
Na początku trzeba dużo pracy zapamiętać, że Python to nie java. Więcej niż banał. W Javie kompilowana jest cała klasa, dzięki czemu rozwiązywanie przestrzeni nazw jest naprawdę proste: wszelkie zmienne zadeklarowane poza metodą (gdziekolwiek) są zmiennymi instancji (lub, jeśli są statyczne, klasowe) i są niejawnie dostępne w ramach metod.
W Pythonie główną zasadą jest to, że istnieją trzy przestrzenie nazw, które są przeszukiwane w kolejności pod kątem zmiennych:
{begin pedagogy}
Istnieją ograniczone wyjątki od tej reguły. Głównym, który przychodzi mi do głowy, jest to, że podczas ładowania definicji klasy definicja klasy jest jej własną niejawną przestrzenią nazw. Ale to trwa tylko tak długo, jak długo moduł jest ładowany i jest całkowicie pomijane, gdy znajduje się w metodzie. A zatem:
ale:
{end pedagogy}
W końcu, rzeczą do zapamiętania jest to, że nie ma dostępu do żadnej z tych zmiennych, które chcesz otworzyć, ale chyba nie w sposób dorozumiany. Jeśli Twoje cele są proste i nieskomplikowane, prawdopodobnie wystarczy Foo.bar lub self.bar. Jeśli Twój przykład staje się bardziej skomplikowany lub chcesz robić wymyślne rzeczy, takie jak dziedziczenie (możesz dziedziczyć metody statyczne / klasowe!), Lub pomysł odwoływania się do nazwy twojej klasy w samej klasie wydaje ci się zły, sprawdź intro, które połączyłem.
źródło
źródło
źródło