2010-08-08 7 views
41
class Example(object): 
    def the_example(self): 
     itsProblem = "problem" 

theExample = Example() 
print(theExample.itsProblem) 

Wie greife ich auf eine Klassenvariable zu? Ich habe versucht, diese Definition hinzuzufügen:Auf die Membervariablen einer Klasse in Python zugreifen?

def return_itsProblem(self): 
    return itsProblem 

Doch das scheitert auch.

+0

Titel bearbeitet Frage eigentlich über Klasse „statische“ Variablen: http://stackoverflow.com/questions/707380/in-python-how-can-i-access- static-class-variables-in-class-methods –

Antwort

80

Die Antwort, in wenigen Worten

In Ihrem Beispiel: itsProblem ist eine lokale Variable.

Sie müssen self verwenden, um Instanzvariablen zu setzen und abzurufen. Sie können es in der __init__ Methode einstellen. Dann würde der Code sein:

class Example(object): 
    def __init__(self): 
     self.itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

Aber wenn Sie eine echte Klassenvariable wollen, dann verwenden Sie den Klassennamen direkt:

class Example(object): 
    itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 
print (Example.itsProblem) 

Aber seien Sie vorsichtig mit dieser, wie theExample.itsProblem automatisch eingestellt werden gleich Example.itsProblem, ist aber nicht die gleiche Variable und kann unabhängig geändert werden.

Einige Erklärungen

In Python Variablen Auto dynamisch erstellt werden.

class Example(object): 
    pass 

Example.itsProblem = "problem" 

e = Example() 
e.itsSecondProblem = "problem" 

print Example.itsProblem == e.itsSecondProblem 

Drucke

Wahre

Deshalb, das ist genau das, was Sie mit den vorherigen Beispielen tun: Dazu können Sie folgendes tun. In Python verwenden wir self als this, aber es ist ein bisschen mehr als das. Self ist das erste Argument für jede Objektmethode, da das erste Argument immer die Objektreferenz ist. Dies ist automatisch, ob Sie es selbst nennen oder nicht.

Was bedeutet, dass Sie tun können:

class Example(object): 
    def __init__(self): 
     self.itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

Oder:

class Example(object): 
    def __init__(my_super_self): 
     my_super_self.itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

Es ist genau das gleiche. Das erste Argument der Objektmethode ANY ist das aktuelle Objekt, wir nennen es nur self als Konvention. Und Sie fügen diesem Objekt nur eine Variable hinzu, genauso wie Sie es von außen tun würden.

Nun zu den Klassenvariablen.

Wenn Sie das tun:

class Example(object): 
    itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

Sie werden wir zuerst bemerken gesetzt eine Klassenvariable, dann greifen wir ein Objekt (Instanz) Variable. Wir setzen diese Objektvariable niemals, aber es funktioniert, wie ist das möglich?

Nun, Python versucht, zuerst die Objektvariable zu bekommen, aber wenn sie es nicht finden kann, wird Ihnen die Klassenvariable geben. Warnung: Die Klassenvariable wird von Instanzen gemeinsam verwendet, die Objektvariable nicht.

Als Schlussfolgerung verwenden Sie nie Klassenvariablen, um Standardwerte für Objektvariablen festzulegen. Verwenden Sie dazu __init__.

Schließlich werden Sie lernen, dass Python-Klassen Instanzen und somit Objekte selbst sind, die neue Erkenntnisse zum Verständnis der oben genannten gibt. Komm zurück und lies das später noch einmal, wenn du das merkst.

+0

+1 für __init__. Dafür ist es da. – Abizern

+0

Sie sagen: "theExample.itsProblem wird automatisch auf Example.itsProblem gesetzt, aber ist nicht die gleiche Variable überhaupt und kann unabhängig geändert werden" - aber das ist nicht ganz richtig, und Ihre Phrase ist irreführend. Ich vertraue darauf, dass Sie wissen, was dort vor sich geht, also schlage ich vor, dass "es _ist_ die gleiche Variable ist, aber es kann für jedes Objekt unabhängig rebindexiert werden". – jsbueno

+0

Ja, aber Binding ist ein Konzept, das jemand für eine andere Programmiersprache wie Java oder C (wie ich vermute, das OP ist) völlig unbekannt ist. Dann würde ich mir erklären, was eine Bindung ist, dann eine späte Bindung, dann das Problem mit Referenzen auf veränderbare Objekte. Es wäre zu lang. Ich denke, irgendwann muss man Präzision auf dem Altar des Verstehens opfern. –

8

Sie deklarieren eine lokale Variable, keine Klassenvariable. Um eine Instanzvariable (Attribut) zu setzen, verwenden

class Example(object): 
    def the_example(self): 
     self.itsProblem = "problem" # <-- remember the 'self.' 

theExample = Example() 
theExample.the_example() 
print(theExample.itsProblem) 

Um ein class variable (auch bekannt als statisches Element) festzulegen, verwenden

class Example(object): 
    def the_example(self): 
     Example.itsProblem = "problem" 
     # or, type(self).itsProblem = "problem" 
     # depending what you want to do when the class is derived. 
+0

Außer dass Klassenvariablen * einmal * auf * Klassenebene * deklariert sind. Ihr Weg wird es bei jeder Instanziierung zurücksetzen, das ist wirklich nicht das, was Sie wollen. Siehe auch http://stackoverflow.com/questions/2709821/python-self-explained für die Begründung hinter expliziten selbst. – delnan

0

Wenn Sie eine Instanz Funktion haben (dh eine, die sich selbst übergeben wird), die Sie selbst verwenden können, einen Verweis auf die Klasse zu erhalten mit self.__ __class__ __

Zum Beispiel in dem folgenden Code Tornado eine Instanz erzeugt Anforderungen zu verarbeiten bekommen, aber wir können die get_handler Klasse erreichen und sie benutzen, um einen riak Client zu halten, so dass wir nicht für jede Anfrage einen erstellen müssen.

import tornado.web 
import riak 

class get_handler(tornado.web.requestHandler): 
    riak_client = None 

def post(self): 
    cls = self.__class__ 
    if cls.riak_client is None: 
     cls.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc') 
    # Additional code to send response to the request ... 
0

Implementieren Sie die Rückgabeanweisung wie im folgenden Beispiel! Du solltest gut sein. Ich hoffe, dass es jemand hilft ...

class Example(object): 
     def the_example(self): 
     itsProblem = "problem" 
     return itsProblem 

    theExample = Example() 
    print theExample.the_example() 
+0

Sie sollten Ihren Code-Einzug beheben. Es gibt auch bessere Antworten auf diese Frage und Ihre Antwort ist eine grundlegende Variation dieser Antworten, keine alternative Lösung ... –

Verwandte Themen