Klasse __init__ (nicht Instanz __init__)

8

Hier ist ein sehr einfaches Beispiel von dem, was ich versuche zu umgehen:

%Vor%

Das Problem ist, dass ich nicht auf Test verweisen kann, während es noch definiert wird

Normalerweise würde ich das einfach machen:

%Vor%

Aber ich erstelle niemals eine Instanz dieser Klasse. Es ist wirklich nur ein Container, der eine Gruppe verwandter Funktionen und Daten enthält (ich habe mehrere dieser Klassen und verteile Referenzen darauf, also ist notwendig, damit Test seine eigene Klasse ist)

Meine Frage ist also, wie kann ich auf Test verweisen, während es definiert wird, oder gibt es etwas, das ähnlich wie __init__ ist, das aufgerufen wird, sobald die Klasse definiert ist? Wenn möglich, möchte ich, dass self.some_dict = {Test: True} innerhalb der Klassendefinition bleibt. Dies ist die einzige Möglichkeit, wie ich das bisher machen kann:

%Vor%     
Ponkadoodle 24.04.2010, 22:32
quelle

5 Antworten

12

Die Klasse existiert tatsächlich nicht, während sie definiert wird. Die class -Anweisung funktioniert so, dass der Hauptteil der Anweisung als ein Block aus Code in einem separaten Namespace ausgeführt wird. Am Ende der Ausführung wird dieser Namespace an die Metaklasse übergeben (z. B. type ), und die Metaklasse erstellt die Klasse unter Verwendung des Namespace als Attributbereich.

Aus Ihrer Beschreibung klingt nicht , dass Test eine Klasse ist. Es klingt, als sollte es stattdessen ein Modul sein. some_dict ist global - selbst wenn es ein Klassenattribut ist, gibt es nur ein solches Attribut in Ihrem Programm, also ist es nicht besser als ein globales - und alle Klassenmethoden, die Sie in der Klasse haben, können nur Funktionen sein.

Wenn Sie wirklich möchten, dass es sich um eine Klasse handelt, haben Sie drei Möglichkeiten: Setzen Sie das Diktat, nachdem Sie die Klasse definiert haben:

%Vor%

Verwenden Sie einen Klassendekorator (in Python 2.6 oder höher):

%Vor%

Oder verwenden Sie eine Metaklasse:

%Vor%     
Thomas Wouters 24.04.2010, 22:41
quelle
4

Sie könnten das some_dict-Attribut nach der Hauptklassendefinition hinzufügen.

%Vor%     
Trey Hunner 24.04.2010 22:38
quelle
1

Ich habe in der Vergangenheit versucht, Klassen auf diese Weise zu verwenden, und es wird ziemlich schnell hässlich (zum Beispiel müssen alle Methoden Klassenmethoden oder statische Methoden sein, und Sie werden wahrscheinlich irgendwann merken, dass Sie das wollen) Definieren Sie spezielle Methoden, für die Sie Metaklassen verwenden müssen). Es könnte die Dinge viel einfacher machen, wenn Sie stattdessen nur Klasseninstanzen verwenden - es gibt wirklich keine Nachteile.

Eine (seltsam aussehende) Alternative zu dem, was andere vorgeschlagen haben: Sie könnten __new__ :

verwenden %Vor%

Sie könnten sogar __new__ einen Verweis auf die Klasse zurückgeben und einen Dekorator verwenden, um sie aufzurufen:

%Vor%     
James 07.06.2012 08:32
quelle
0

Sie können auch eine Metaklasse verwenden (hier eine Funktion, aber es gibt andere Möglichkeiten):

%Vor%     
fraca7 26.04.2010 07:33
quelle
0

Thomas 'erstes Beispiel ist sehr gut, aber hier ist eine mehr pythonische Art, dasselbe zu tun.

%Vor%     
darkfeline 07.06.2012 08:13
quelle