2016-08-23 3 views
1

in neuestem Python 2.7.x:Wie spezifiziert man eine Variable als Elementvariable einer Klasse oder einer Instanz der Klasse?

  1. jedes Mitglied Variable innerhalb der Definition einer Klasse Gegeben ist die Membervariable auf Klassenebene in dem Sinne, dass es immer eine einzelne Variable von allen Instanzen gemeinsam genutzt wird der Klasse?

  2. In der Definition einer Klasse, wie kann ich

    • die Membervariablen in der Definition einer Klasse angeben, zu der Klasse gehören und damit von allen Instanzen der Klasse geteilt, und
    • welche gehören zu einer bestimmten Instanz der Klasse und nicht zu einer anderen Instanz der Klasse?
  3. Wie kann ich auf eine Membervariable einer Klasse verweisen?

    Wie kann ich auf eine Membervariable einer Instanz einer Klasse verweisen?

  4. Werden die Antworten auf die obigen Fragen irgendwo in der offiziellen Python-Sprachreferenz https://docs.python.org/2/reference/ angezeigt? Ich kann sie dort nicht finden.

Danke.

+0

Im Allgemeinen können Sie nicht sagen. Aber das ist auch nicht relevant. – Daniel

+0

Sie könnten nach ["9.3.5. Klassen- und Instanzvariablen"] (https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables) suchen, was die meisten davon abdeckt was du fragst. –

+0

Wie können Sie feststellen, in welchem ​​Kontext? Programmgesteuert prüfen? Quellcode ansehen? –

Antwort

1

Sie könnten hier die terminology "Klassenvariable" und "Instanzvariable" verwenden, da dies die übliche Sprache in Python ist.

class Foo(object): 

    var1 = "I'm a class variable" 

    def __init__(self, var2): 
     self.var2 = var2 # var2 is an instance variable 

Die einzige Scoping-Regel, die Sie wirklich brauchen, in Python wissen, ist die Suchreihenfolge für Namen - „LEGB“, für lokale, Enclosing, Globale und Builtin.

Die Klassenbereichsvariable var1 muss immer noch nach "get attribute" gesucht werden, Sie können nur auf diese durch Foo.var1 oder self.var1 zugreifen. Natürlich können Sie auch anderswo innerhalb des Klassendefinitionsblocks darauf zugreifen, aber das ist nur eine Beispielverwendung aus dem Bereich "Lokal". Wenn Sie self.var1 sehen, können Sie nicht sofort wissen, ob es sich um eine Instanz oder eine Klassenvariable handelt (und auch nicht, wenn der Name überhaupt an ein Objekt gebunden ist!). Sie wissen nur, dass das get-Attribut auf dem Objekt selbst versucht wird, bevor es in der Klasse versucht wird.

der Tat kann eine Instanzvariable eine Klassenvariable mit dem gleichen Namen Schatten:

>>> f1 = Foo(var2='f1_2') 
>>> f2 = Foo(var2='f2_2') 
>>> f2.var1 
"I'm a class variable" 
>>> f2.var1 = "Boom!" # this shadows the class variable 
>>> f1.var1, Foo.var1, f2.var1 # but: the class variable still exists 
("I'm a class variable", "I'm a class variable", 'Boom!') 
>>> del f2.var1 # restores the name resolution on the Foo object 
>>> f2.var1 
"I'm a class variable" 

Angelegenheiten erschweren, können wir Phantasie Code schreiben, die Klassenvariablen verhalten sich eher wie Instanzvariablen macht; Ein bemerkenswertes Beispiel sind "Felder" eines ORM. In Django können Sie beispielsweise ein Integer-Feld für die Klasse model definieren. Wenn Sie jedoch diesen Namen für eine Instanz des Modells suchen, wird eine tatsächliche Ganzzahl zurückgegeben (kein IntegerField-Objekt).

Wenn Sie an dieser fortgeschrittenen Verwendung von Attributzugriff interessiert sind, lesen Sie die descriptor protocol.Für alltägliche Klassen können Sie diese Details ignorieren, aber es ist wert zu wissen, dass die übliche Auflösung von Instanzvariablen und Klassenvariablen niedrigere Priorität als alle Deskriptoren, die möglicherweise für die Klasse definiert wurden.

+0

danke. ist es richtig, dass eine Variable einer Instanz nur innerhalb des Funktionskörpers von _init (self, ...) definiert werden kann? – Tim

+0

@Tim Es könnte einfacher sein, darüber nachzudenken, wo Sie eine Klassenvariable erstellen können und was nicht, da dies sehr viel eingeschränkter ist. Instanzvariablen können an vielen Stellen erstellt werden. Vielleicht möchten Sie etwas komplexere Sachen wie [Deskriptoren] (http://nedbatchelder.com/blog/201306/explaining_descriptors.html) und [Metaklassen] (https://jakevdp.github.io/blog/2012) lesen/12/01/a-primer-on-python-metaclasses /), weil es Ihnen eine viel bessere Vorstellung von der zugrundeliegenden Maschinerie gibt und wie sie normalerweise verwendet wird. –

+0

@Tim Nein, das ist nicht korrekt. Sie können sie auch außerhalb von '__init__' erstellen. – wim

Verwandte Themen