Zusammengesetzte Zuweisung zu Python-Klassen-und Instanz-Variablen
Ich habe versucht zu verstehen, Python-Behandlung von Klasse und Instanz-Variablen. Insbesondere fand ich diese Antwort sehr hilfreich. Im Grunde es sagt, dass, wenn Sie deklarieren eine Klasse variable, und dann müssen Sie eine Zuordnung zu [instance].property
werden Sie die Zuweisung an eine andere variable zusammen -- in einem anderen namespace, die von der Klasse variable.
So, dann überlegte ich, -- wenn ich will, dass jede Instanz meiner Klasse haben ein Mitglied mit einigen default-Wert (z.B. null), sollte ich es so machen:
class Foo:
num = 0
oder so?
class Foo:
def __init__(self):
self.num = 0
Basiert auf, was ich früher gelesen, würde ich denken, dass das zweite Beispiel wäre der Initialisierung der 'rechts' - variable (Instanz anstelle der class-variable). Allerdings finde ich, dass die erste Methode funktioniert sehr gut, auch:
class Foo:
num = 0
bar = Foo()
bar.num += 1 # good, no error here, meaning that bar has an attribute 'num'
bar.num
>>> 1
Foo.num
>>> 0 # yet the class variable is not modified! so what 'num' did I add to just now?
Also.. warum funktioniert das? Was bekomme ich nicht? FWIW, meine Vorherige Verständnis der OOP von C++, so die Erklärung durch Analogie (oder zeigen, wo es bricht unten) nützlich sein könnten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Persönlich, ich habe festgestellt, diese Dokumente von Shalabh Chaturvedi sehr hilfreich und informativ in Bezug auf diesen Sachverhalt.
bar.num += 1
ist eine Kurzform fürbar.num = bar.num + 1
. Dies ist die Abholung der Klasse variableFoo.num
auf der rechten Seite und die Zuordnung zu einer Instanz-variablebar.num
.variable
was ich wirklich meine istattribute
.In den folgenden code
num
ist eine Klasse Mitglied.Einer C++ - äquivalent wäre so etwas wie
self.num
ist eine Instanz Mitglied (self
wird eine Instanz vonFoo
).In C++, es wäre so etwas wie
Ich glaube, dass Python ermöglicht es Ihnen, eine Klasse und eine Instanz Mitgliedstaaten teilen den gleichen Namen (C++ nicht). Also, wenn Sie
bar = Foo()
,bar
ist eine Instanz vonFoo
, also mitbar.num += 1
erhöhen Sie die Instanz-member.erstellt eine neue Instanz der variable 'num' auf 'bar' Beispiel, weil es noch nicht existiert (und dann 1 addiert zu diesem Wert)
Beispiel:
diese Drucke 1
dieser gibt einen Fehler, als erwartet: Traceback (most recent call last):
File "", line 1, in
AttributeError: Foo-Instanz hat kein Attribut 'foo'
nun diese Drucke 5
was passiert also in deinem Beispiel: bar.num gelöst Foo.num, weil es nur ein class-Attribut. dann foo.num ist eigentlich erstellt, weil Sie einen Wert zuweisen, um es.
bar.foo += 1
gibt auch einen Fehler, so deutlich Python erstellt keine Instanz-Variablen, wenn es auf Sie Sie in einem Ausdruck mit '+='. Meine Frage ist, wie Erstellung von class-Variablen führen Sie die Initialisierung der entsprechenden Instanz-Variablen?num
in diesem Fall), dann den Typ des Objekts (Foo
) in diesem Fall, dann die Basis-Klassen von den Typ des Objekts und deren Basen. Wenn kein passendes Attribut gefunden wirdAttributeError
ausgelöst.Suche für diese Frage, sowohl in diesem StackOverflow-Frage und zwei (ziemlich alte, aber gültige) Folien, die von Guido van Rossum (Eins, Zwei) kam hoch. Guido Folien Zustand dieses Verhalten hat zu tun mit Python suchen, um für den Zugriff auf das Attribut (in dem Fall des Beispiels oben
num
). Dachte, es wäre schön, die beiden zusammen hier richtig 🙂Ich glaube, Sie haben gerade ein bug in Python gibt. bar.num += 1 sollte ein Fehler sein, statt, es ist die Schaffung einer Attribut num in der Objekt bar, die sich deutlich von Foo.num.
Es ist ein wirklich seltsames Verhalten.