2012-05-20 11 views
66

En python, quiero que una clase tenga algunas "constantes" (prácticamente variables) que serán comunes en todas las subclases. ¿Hay alguna manera de hacerlo con sintaxis amigable? Ahora mismo uso:Constantes de clase en python

class Animal: 
    SIZES=["Huge","Big","Medium","Small"] 

class Horse(Animal): 
    def printSize(self): 
     print(Animal.SIZES[1]) 

y me pregunto si hay una mejor manera de hacerlo o una manera de hacerlo sin tener que escribir a continuación, "Animal". antes de los tamaños. Gracias! editar: se me olvidó mencionar que el caballo hereda de un animal.

+9

No es una respuesta completa, pero si 'SIZES' nunca cambia, definitivamente el uso de una tupla en lugar de una lista . Al igual que '(" Enorme "," Grande "," Medio "," Pequeño ")' – jamylak

+0

Parece que realmente estás detrás de una enumeración aquí – Eric

Respuesta

12

Puede obtener SIZES por medio de self.SIZES (en un método de instancia) o cls.SIZES (en un método de clase).

En cualquier caso, tendrá que ser explícito sobre dónde encontrar SIZES. Una alternativa es poner SIZES en el módulo que contiene las clases, pero luego debe definir todas las clases en un solo módulo.

+0

El caballo es de hecho una subclase de Animal. En realidad, es perfectamente posible usar self.SIZES [1] en lugar de Animal.SIZES [1]. – betabandido

+0

@betabandido: el OP corrigió la pregunta. Actualizará la respuesta en consecuencia. –

6
class Animal: 
    HUGE = "Huge" 
    BIG = "Big" 

class Horse: 
    def printSize(self): 
     print(Animal.HUGE) 
+0

También puede acceder a través de sí mismo, ej. "self.HUGE" o "self.BIG". Esto solo funcionaría internamente dentro de la clase. – cevaris

82

Desde Horse es una subclase de Animal, puede simplemente cambiar

print(Animal.SIZES[1]) 

con

print(self.SIZES[1]) 

Sin embargo, es necesario recordar que SIZES[1] significa "grande", por lo que probablemente se podría mejorar su código haciendo algo como:

class Animal: 
    SIZE_HUGE="Huge" 
    SIZE_BIG="Big" 
    SIZE_MEDIUM="Medium" 
    SIZE_SMALL="Small" 

class Horse(Animal): 
    def printSize(self): 
     print(self.SIZE_BIG) 

Como alternativa, puede crear clases intermedias: HugeAnimal, BigAnimal, y así sucesivamente. Eso sería especialmente útil si cada clase de animal contendrá una lógica diferente.

2

Ampliando la respuesta de betabandido, se podría escribir una función para inyectar los atributos como constantes en el módulo:

def module_register_class_constants(klass, attr_prefix): 
    globals().update(
     (name, getattr(klass, name)) for name in dir(klass) if name.startswith(attr_prefix) 
    ) 

class Animal(object): 
    SIZE_HUGE = "Huge" 
    SIZE_BIG = "Big" 

module_register_class_constants(Animal, "SIZE_") 

class Horse(Animal): 
    def printSize(self): 
     print SIZE_BIG 
+0

'print SIZE_BIG' fuera de clase será el mismo? ¿Será editable 'Animal.SIZE_HUGE = 'Small''? – Crusader

Cuestiones relacionadas