wake-up-neo.net

Zugriff auf Member-Variablen einer Klasse in Python?

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

theExample = Example()
print(theExample.itsProblem)

Wie greife ich auf die Variable einer Klasse zu? Ich habe versucht, diese Definition hinzuzufügen:

def return_itsProblem(self):
    return itsProblem

Das scheitert aber auch.

53
Adam

Die Antwort in wenigen Worten

In Ihrem Beispiel ist itsProblem eine lokale Variable.

Sie müssen self verwenden, um Instanzvariablen festzulegen und abzurufen. Sie können es in der __init__ -Methode einstellen. Dann wäre Ihr Code:

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


theExample = Example()
print(theExample.itsProblem)

Wenn Sie jedoch eine echte Klassenvariable möchten, verwenden Sie den Klassennamen direkt:

class Example(object):
    itsProblem = "problem"


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

Aber seien Sie vorsichtig mit diesem Wert, da theExample.itsProblem automatisch auf Example.itsProblem gesetzt wird, aber nicht dieselbe Variable ist und unabhängig geändert werden kann.

Einige Erklärungen

In Python können Variablen dynamisch erstellt werden. Daher können Sie Folgendes tun:

class Example(object):
    pass

Example.itsProblem = "problem"

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

print Example.itsProblem == e.itsSecondProblem 

druckt

Wahr

Deshalb machen Sie genau das mit den vorherigen Beispielen.

In Python verwenden wir self als this, aber es ist ein bisschen mehr. self ist das erste Argument für eine Objektmethode, da das erste Argument immer die Objektreferenz ist. Dies geschieht automatisch, unabhängig davon, ob Sie es self nennen oder nicht.

Was bedeutet, dass Sie Folgendes 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 von JEDER Objektmethode ist das aktuelle Objekt, wir nennen es nur self als Konvention. Und Sie fügen nur eine Variable hinzu dieses Objekt, so 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 feststellen, dass wir zuerst eine Klassenvariable setzen, dann eine Objekt- (Instanz-) Variable zugreifen. Wir haben diese Objektvariable nie gesetzt, aber sie funktioniert. Wie ist das möglich?

Nun, Python versucht zuerst die Objektvariable abzurufen, aber wenn sie nicht gefunden wird, erhalten Sie die Klassenvariable. Warnung: Die Klassenvariable wird von mehreren Instanzen gemeinsam genutzt und die Objektvariable nicht.

Verwenden Sie daher niemals Klassenvariablen, um Standardwerte für Objektvariablen festzulegen. Verwenden Sie dazu __init__.

Mit der Zeit werden Sie feststellen, dass Python Klassen Instanzen und daher Objekte selbst sind, was neue Erkenntnisse zum Verständnis des oben Gesagten bietet. Komm zurück und lies das später noch einmal, wenn du das merkst.

117
e-satis

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

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

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

Verwenden Sie zum Festlegen einer class-Variable (a.k.a. statischer Member)

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.
9
kennytm

Wenn Sie eine Instanzfunktion haben (d. H. Eine Funktion, die self übergeben wird), können Sie self verwenden, um mithilfe von self.__class__ einen Verweis auf die Klasse zu erhalten.

Im folgenden Code erstellt tornado beispielsweise eine Instanz, um Abrufanforderungen zu verarbeiten. Wir können jedoch die Klasse get_handler verwenden, um einen Riak-Client zu speichern, sodass nicht für jede Anforderung eine erstellt werden muss. 

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
andrew pate