2010-03-30 6 views
8

Excuses si j'ai la mauvaise terminologie ici-je ne peux pas penser à ce que cet idiome particulier serait appelé.Créer des instances statiques d'une classe à l'intérieur de cette classe en Python

J'ai essayé de créer une classe Python 3 qui déclare statiquement des instances de lui-même à l'intérieur de lui-même - un peu comme une énumération fonctionnerait. Voici une version simplifiée du code je l'ai écrit:

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)) 

écriture, je suis une exception sur la ligne 2 (A = Test("A")). Je suppose que la ligne 3 serait également erronée si elle l'avait fait jusque-là. L'utilisation de __class__ au lieu de Test donne la même erreur.

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

Y a-t-il un moyen de faire référence à la classe actuelle dans un contexte statique en Python? Je pourrais déclarer ces variables particulières en dehors de la classe ou dans une classe séparée, mais pour des raisons de clarté, je préférerais ne pas pouvoir l'aider.

Pour mieux illustrer ce que je suis en train de faire, voici le même exemple en 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); 
    } 
} 

Cela fonctionne comme on peut s'y attendre: il imprime:

Test: A 
Test: B 

Comment puis-je faire la même chose en Python?

Répondre

9

Après avoir défini la classe, il suffit d'ajouter ces deux lignes:

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

Une classe en Python est un objet comme un autre et vous pouvez ajouter de nouvelles variables à tout moment. Vous ne pouvez pas le faire à l'intérieur de la classe car il n'est pas défini à ce moment-là (il sera ajouté à la table des symboles seulement après que le code entier de la classe a été analysé correctement).

+0

Bien sûr -CAN'T crois que je ne l'ai pas vu cela. Merci beaucoup pour votre aide. –

2

En Python, un bloc class n'est pas qu'une simple déclaration; il est exécuté au moment de l'exécution pour construire la classe. Chaque def à l'intérieur de la classe construit une fonction et lie le nom dans l'espace de noms de la classe. Pour cette raison, vous ne pouvez pas simplement faire A = MyClass() directement dans le bloc de classe, car MyClass() n'est pas entièrement défini tant que le bloc de classe ne se ferme pas. Voici comment faire:

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

Alors que la réponse d'Aaron est le moyen préféré vous pouvez également utiliser métaclasses:

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

Assez cool. Les métaclasses sont quelque chose que je n'ai jamais joué auparavant. Je vais devoir les essayer à un moment donné. –

Questions connexes