2010-03-30 10 views
8

Disculpas si tengo la terminología mal aquí, no puedo pensar lo que este lenguaje particular, sería llamado.crear instancias estáticas de una clase dentro de dicha clase en Python

que he estado tratando de crear una clase de Python 3 que declara estáticamente instancias de sí mismo dentro de sí mismo, algo así como una enumeración funcionaría. Aquí hay una versión simplificada del código que he escrito:

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

Escribiendo esto, tengo una excepción en la línea 2 (A = Test("A")). Supongo que la línea 3 también sería un error si hubiera llegado tan lejos. Usando __class__ en lugar de Test da el mismo error.

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

¿Hay alguna manera de referirse a la clase actual en un contexto estático en Python? Podría declarar estas variables particulares fuera de la clase o en una clase separada, pero, por cuestiones de claridad, preferiría no hacerlo si puedo evitarlo.

Para demostrar mejor lo que estoy tratando de hacer, aquí está el mismo ejemplo 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); 
    } 
} 

Esto funciona como era de esperar: se imprime:

Test: A 
Test: B 

¿Cómo puedo hacer lo mismo en Python?

Respuesta

9

Después de que haya definido la clase, sólo tiene que añadir estas dos líneas:

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

Una clase en Python es un objeto como cualquier otro y se pueden añadir nuevas variables en cualquier momento. Usted simplemente no puede hacerlo dentro de la clase ya que no está definida en ese momento (que se añadirá a la tabla de símbolos sólo después de que todo el código de la clase se ha analizado correctamente).

+0

Por supuesto-no puedo creer que no lo veo. Muchas gracias por su ayuda. –

2

En Python, un bloque class no es sólo una declaración; se ejecuta en tiempo de ejecución para construir la clase. Cada def dentro de la clase crea una función y vincula el nombre al espacio de nombres de la clase. Por esa razón, no se puede simplemente hacer A = MyClass() directamente en el interior del bloque de clases, porque MyClass() no está completamente definido hasta que el bloque de clase se cierra. He aquí cómo hacerlo:

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

Mientras que la respuesta de la Aaron es la manera preferida también se puede utilizar metaclases:

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

Bastante bien. Las metaclases son algo con lo que no he jugado antes. Tendré que probarlos en algún momento. –

Cuestiones relacionadas