Wie kann ich auf “statische” Klassenvariablen innerhalb von Methoden in Python zugreifen?

Lesezeit: 5 Minuten

Wie kann ich auf statische Klassenvariablen innerhalb von Methoden in
Ross Rogers

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?

  • Weitere Informationen zu Python und Statik finden Sie hier: stackoverflow.com/questions/68645/python-static-variable

    – Bettwyr

    1. April 09 um 21:57 Uhr

Anstatt bar benutzen self.bar oder Foo.bar. Zuordnung zu Foo.bar wird eine statische Variable erstellen und zuweisen self.bar erstellt eine Instanzvariable.

  • Foo.bar wird funktionieren, aber self.bar erstellt eine Instanzvariable, keine statische.

    – Bettwyr

    1. April 09 um 21:55 Uhr

  • bedwyr, “print self.bar” erstellt keine Instanzvariablen (obwohl die Zuweisung an self.bar dies tut).

    – Konstantin

    1. April 09 um 22:14 Uhr

  • @Constantin – Das war mir nicht klar, es ist eine interessante Unterscheidung. Danke für die Korrektur 🙂

    – Bettwyr

    3. April 09 um 1:14 Uhr

  • Aber wenn Sie nicht beabsichtigen, dass es einen Ivar gibt, ist es klarer, Foo.classmember zu verwenden.

    – mk12

    13. September 2009 um 20:58 Uhr

  • Wenn Sie statische Variablen verwenden, ist es eine gute Idee, die Fallstricke von hier zu lesen: stackoverflow.com/questions/68645/… . @Constantin gibt einen der vielen Fallstricke.

    – Trevor Boyd Smith

    21. März 17 um 16:27 Uhr


Wie kann ich auf statische Klassenvariablen innerhalb von Methoden in
vartec

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

  • Warum nicht einfach Foo.bar statt self.__class__.bar?

    – mk12

    13. September 2009 um 20:59 Uhr

  • @Mk12: Wenn Sie Klassenvererbung haben, könnte sich eine “Klassenvariable” in einer Basisklasse oder einer Unterklasse befinden. Auf welche möchten Sie sich beziehen? Hängt davon ab, was Sie versuchen zu tun. Foo.bar würde immer auf ein Attribut der angegebenen Klasse verweisen – die eine Basisklasse oder eine Unterklasse sein könnte. self.__class__.bar würde sich auf die Klasse beziehen, von der die Instanz ein Typ ist.

    – Craig McQueen

    11. Dezember 2009 um 4:47 Uhr

  • Jetzt haben wir den unglücklichen Punkt erreicht, an dem wir uns der Details der Sprache so bewusst werden, dass wir zwischen zwei fein abgestimmten Anwendungsfällen unterscheiden können. Es hängt in der Tat davon ab, was Sie tun möchten, aber viele Leute werden sich nicht um solche Feinheiten kümmern.

    – Holdenweb

    14. Dezember 11 um 10:19 Uhr

  • Übrigens, dies ist eine SELTENE Verwendung von “Klassenvariable”. Viel häufiger wird es in einer bestimmten Klasse definiert, hier Foo. Dies sind nützliche Informationen für einige fortgeschrittene Programmiersituationen. Aber mit ziemlicher Sicherheit nicht das, was die ursprüngliche Frage als Antwort wollte (jeder, der DIESE Antwort braucht, weiß bereits, wie man Foo.bar macht). +1, weil ich daraus etwas gelernt habe.

    – WerkzeugmacherSteve

    25. November 13 um 17:05 Uhr


  • Ich lerne, wann Klassenvariablen und -methoden verwendet werden (im Gegensatz zu Instanzvariablen und -methoden). Wenn Sie in einer Instanzmethode auf eine Klassenvariable zugreifen möchten, ist es dann notwendig, self.__class__.bar zu verwenden? Mir ist aufgefallen, dass self.bar funktioniert, obwohl bar eine Klassenvariable und keine Instanzvariable ist.

    – Rechnung

    29. März ’15 um 18:30 Uhr

1643912769 812 Wie kann ich auf statische Klassenvariablen innerhalb von Methoden in
David Berger

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:

  1. Die Funktion/Methode
  2. Das aktuelle Modul
  3. 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.

  • IIRC, es werden technisch gesehen 3(+) Namespaces durchsucht – funktionslokal, modul/global und eingebaut. Verschachtelte Bereiche bedeuten, dass mehrere lokale Bereiche durchsucht werden können, aber das ist einer der Ausnahmefälle. (…)

    – Jeff Shannon

    2. April 09 um 8:52 Uhr

  • Außerdem würde ich vorsichtig sein, „Hauptmodul“ zu sagen, da es das enthaltende Modul der Funktion ist, das durchsucht wird, nicht das hauptsächlich Modul … Und das Nachschlagen des Attributs aus einer Instanzreferenz ist eine andere Sache, aber diese Antwort erklärt es warum Sie benötigen die Instanz-/Klassenreferenz.

    – Jeff Shannon

    2. April 09 um 8:57 Uhr

Wie kann ich auf statische Klassenvariablen innerhalb von Methoden in
Allan Mwesigwa

class Foo(object):
     bar = 1
     def bah(self):
         print Foo.bar

f = Foo() 
f.bah()

1643912770 700 Wie kann ich auf statische Klassenvariablen innerhalb von Methoden in
Parik Chudasma

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.

  • Erwägen Sie, weitere Informationen hinzuzufügen, um Ihre Antwort zu erweitern, oder bearbeiten Sie andere Antworten, um dieses Detail hinzuzufügen.

    – Benutzer1010

    5. Januar 21 um 18:59 Uhr

  • Erwägen Sie, weitere Informationen hinzuzufügen, um Ihre Antwort zu erweitern, oder bearbeiten Sie andere Antworten, um dieses Detail hinzuzufügen.

    – Benutzer1010

    5. Januar 21 um 18:59 Uhr

.

758630cookie-checkWie kann ich auf “statische” Klassenvariablen innerhalb von Methoden in Python zugreifen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy