Constantes de clase en python


128

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 una sintaxis amigable? Ahora mismo uso:

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 "Animal". antes de los tamaños. ¡Gracias! editar: olvidé mencionar que el caballo hereda de los animales.


16
No es una respuesta completa, pero si SIZESnunca cambia, definitivamente use una tupla en lugar de una lista. Me gusta así("Huge","Big","Medium","Small")
jamylak

Parece que realmente estás buscando una enumeración aquí
Eric

Respuestas:


141

Como Horsees una subclase de Animal, solo puedes cambiar

print(Animal.SIZES[1])

con

print(self.SIZES[1])

Aún así, debe recordar que SIZES[1]significa "grande", por lo que probablemente 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, BigAnimaly así sucesivamente. Eso sería especialmente útil si cada clase de animales contendría una lógica diferente.


SIZE_BIG = ["BigOne", "BigTwo"] debo usar este tipo de constante.
Lova Chittumuri

17

Puede acceder SIZESmediante 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 colocar SIZESel módulo que contiene las clases, pero luego debe definir todas las clases en un solo módulo.


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

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

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

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

También puedes acceder por tu cuenta, ej. "self.HUGE" o "self.BIG". Esto solo funcionaría internamente dentro de la clase.
cevaris

4

Ampliando la respuesta de betabandido, 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

print SIZE_BIGfuera de clase será lo mismo? ¿Será editable Animal.SIZE_HUGE = 'Small'?
Cruzado
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.