Wenn ich folgenden Code habe:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
Es klagt
NameError: Der globale Name „Bar“ ist nicht definiert
Wie kann ich auf Klasse/statische Variable zugreifen bar
innerhalb der Methode bah
?
Anstatt bar
benutzen self.bar
oder Foo.bar
. Zuordnung zu Foo.bar
wird eine statische Variable erstellen und zuweisen self.bar
erstellt eine Instanzvariable.
Klassenmethode definieren:
class Foo(object):
bar = 1
@classmethod
def bah(cls):
print cls.bar
Wenn jetzt bah()
muss eine Instanzmethode sein (dh Zugriff auf sich selbst haben), können Sie immer noch direkt auf die Klassenvariable zugreifen.
class Foo(object):
bar = 1
def bah(self):
print self.bar
Wie bei allen guten Beispielen haben Sie das, was Sie eigentlich versuchen, vereinfacht. Das ist gut, aber es ist erwähnenswert, dass Python eine hat viel der Flexibilität, wenn es um Klassen- und Instanzvariablen geht. Dasselbe gilt für Methoden. Für eine gute Liste der Möglichkeiten empfehle ich die Lektüre Michael Fötsch’ neu gestaltete Klasseneinführung, insbesondere die Abschnitte 2 bis 6.
Eine Sache, die viel Arbeit erfordert, um sich am Anfang daran zu erinnern, ist das Python ist nicht Java. Mehr als nur ein Klischee. In Java wird eine ganze Klasse kompiliert, was die Namensraumauflösung sehr einfach macht: Alle Variablen, die außerhalb einer Methode (irgendwo) deklariert werden, sind Instanzvariablen (oder, falls statisch, Klassenvariablen) und sind implizit innerhalb von Methoden zugänglich.
Bei Python lautet die Faustregel, dass es drei Namespaces gibt, die der Reihe nach nach Variablen durchsucht werden:
- Die Funktion/Methode
- Das aktuelle Modul
- Einbauten
{begin pedagogy}
Hiervon gibt es begrenzte Ausnahmen. Der wichtigste, der mir auffällt, ist, dass beim Laden einer Klassendefinition die Klassendefinition ihr eigener impliziter Namensraum ist. Dies dauert jedoch nur so lange, wie das Modul geladen wird, und wird innerhalb einer Methode vollständig umgangen. Daher:
>>> class A(object):
foo = 'foo'
bar = foo
>>> A.foo
'foo'
>>> A.bar
'foo'
aber:
>>> class B(object):
foo = 'foo'
def get_foo():
return foo
bar = get_foo()
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
class B(object):
File "<pyshell#11>", line 5, in B
bar = get_foo()
File "<pyshell#11>", line 4, in get_foo
return foo
NameError: global name 'foo' is not defined
{end pedagogy}
Am Ende ist die Sache, an die Sie sich erinnern sollten, dass Sie tun Zugriff auf alle Variablen haben, auf die Sie zugreifen möchten, aber wahrscheinlich nicht implizit. Wenn Ihre Ziele einfach und geradlinig sind, reicht es wahrscheinlich aus, sich für Foo.bar oder self.bar zu entscheiden. Wenn Ihr Beispiel komplizierter wird oder Sie ausgefallene Dinge wie Vererbung machen möchten (Sie können statische Methoden/Klassenmethoden erben!) oder Ihnen die Idee, auf den Namen Ihrer Klasse innerhalb der Klasse selbst zu verweisen, falsch erscheint, probieren Sie es aus das von mir verlinkte Intro.
class Foo(object):
bar = 1
def bah(self):
print Foo.bar
f = Foo()
f.bah()
bar
ist Ihre statische Variable und Sie können mit darauf zugreifen Foo.bar
.
Grundsätzlich müssen Sie Ihre statische Variable mit dem Klassennamen qualifizieren.
.
Weitere Informationen zu Python und Statik finden Sie hier: stackoverflow.com/questions/68645/python-static-variable
– Bettwyr
1. April 09 um 21:57 Uhr