2010-03-30 10 views
8

Entschuldigung, wenn ich die Terminologie hier falsch habe - ich kann nicht denken, was diese bestimmte Redewendung würde genannt werden.Erstellen Sie statische Instanzen einer Klasse innerhalb der Klasse in Python

Ich habe versucht, eine Python 3-Klasse zu erstellen, die Instanzen von sich selbst in sich selbst deklariert - so etwas wie ein Enum würde funktionieren. Hier ist eine vereinfachte Version des Code, den ich schrieb:

class Test: 
    A = Test("A") 
    B = Test("B") 

    def __init__(self, value): 
     self.value = value 

    def __str__(self): 
     return "Test: " + self.value 

print(str(Test.A)) 
print(str(Test.B)) 

dieses Schreiben, bekam ich eine Ausnahme auf der Linie 2 (A = Test("A")). Ich nehme an, Zeile 3 wäre auch fehlerhaft, wenn es so weit gekommen wäre. Die Verwendung von __class__ anstelle von Test gibt den gleichen Fehler.

File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in Test 
NameError: name 'Test' is not defined 

Gibt es eine Möglichkeit, in Python auf die aktuelle Klasse in einem statischen Kontext zu verweisen? Ich könnte diese besonderen Variablen außerhalb der Klasse oder in einer separaten Klasse deklarieren, aber aus Gründen der Klarheit möchte ich lieber nicht, wenn ich es helfen kann.

besser Um zu zeigen, was ich versuche zu tun, hier ist das gleiche Beispiel in Java:

public class Test { 
    private static final Test A = new Test("A"); 
    private static final Test B = new Test("B"); 

    private final String value; 

    public Test(String value) { 
     this.value = value; 
    } 

    public String toString() { 
     return "Test: " + value; 
    } 

    public static void main(String[] args) { 
     System.out.println(A); 
     System.out.println(B); 
    } 
} 

Dies als Sie arbeitet erwarten würde: er druckt:

Test: A 
Test: B 

Wie kann ich tun das gleiche in Python?

Antwort

9

Nachdem Sie die Klasse definiert, fügen Sie einfach diese beiden Zeilen:

Test.A = Test("A") 
Test.B = Test("B") 

Eine Klasse in Python ein Objekt wie jedes andere ist, und Sie können jederzeit neue Variablen hinzufügen. Sie können es einfach nicht innerhalb der Klasse tun, da es zu diesem Zeitpunkt nicht definiert ist (es wird erst dann in die Symboltabelle eingefügt, wenn der gesamte Code für die Klasse korrekt analysiert wurde).

+0

Natürlich-kann glaube ich nicht, dass sehen. Vielen Dank für Ihre Hilfe. –

2

In Python ist ein class Block nicht nur eine Deklaration; Es wird zur Laufzeit ausgeführt, um die Klasse zu erstellen. Jedes def innerhalb der Klasse erstellt eine Funktion und bindet den Namen in den Klassennamespace. Aus diesem Grund können Sie A = MyClass() nicht direkt innerhalb des Klassenblocks ausführen, da MyClass() erst vollständig definiert ist, wenn der Klassenblock geschlossen wird. Hier ist, wie es zu tun:

class Test: 
    def __init__(self, value): 
     self.value = value 

    def __str__(self): 
     return "Test: " + self.value 

Test.A = Test("A") 
Test.B = Test("B") 
2

Während die Aaron Antwort die bevorzugte Art und Weise ist, dass Sie auch metaclasses verwenden können:

>>> class TestMeta(type): 
... def __init__(cls, name, bases, dct): 
... cls.A = cls() 
... cls.B = cls() 
... 
>>> class Test: 
... __metaclass__ = TestMeta 
... 
>>> Test 
<class __main__.Test at 0x7f70f8799770> 
>>> Test.A 
<__main__.Test object at 0x7f70f86f2e10> 
>>> Test.B 
<__main__.Test object at 0x7f70f86f2e90> 
>>> 
+0

Ziemlich cool. Metaklassen sind etwas, mit dem ich noch nie gespielt habe. Ich werde sie irgendwann ausprobieren müssen. –

Verwandte Themen