Costanti di classe in Python


128

In Python, voglio che una classe abbia alcune "costanti" (praticamente variabili) che saranno comuni in tutte le sottoclassi. C'è un modo per farlo con una sintassi amichevole? In questo momento uso:

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

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

e mi chiedo se c'è un modo migliore per farlo o un modo per farlo senza dover scrivere "Animale". prima delle dimensioni. Grazie! modifica: ho dimenticato di menzionare che il cavallo eredita dall'animale.


16
Non è una risposta completa ma se SIZESnon cambia mai, usa sicuramente una tupla invece di un elenco. In questo modo("Huge","Big","Medium","Small")
jamylak,

Sembra che tu stia davvero cercando un enum qui
Eric,

Risposte:


141

Poiché Horseè una sottoclasse di Animal, puoi semplicemente cambiare

print(Animal.SIZES[1])

con

print(self.SIZES[1])

Tuttavia, devi ricordare che SIZES[1]significa "grande", quindi probabilmente potresti migliorare il tuo codice facendo qualcosa del tipo:

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

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

In alternativa, è possibile creare classi intermedie: HugeAnimal, BigAnimal, e così via. Ciò sarebbe particolarmente utile se ogni classe animale conterrà una logica diversa.


SIZE_BIG = ["BigOne", "BigTwo"] dovrei usare questo tipo di costante.
Lova Chittumuri,

17

Puoi accedervi SIZEStramite self.SIZES(in un metodo di istanza) o cls.SIZES(in un metodo di classe).

In ogni caso, dovrai essere esplicito su dove trovare SIZES. Un'alternativa è quella di inserire SIZESil modulo contenente le classi, ma è necessario definire tutte le classi in un singolo modulo.


Il cavallo è davvero una sottoclasse di animali. In realtà, è perfettamente possibile usare self.SIZES [1] invece di Animal.SIZES [1].
Betabandido,

@betabandido: l'OP ha corretto la domanda. Aggiornerà la risposta di conseguenza.
Fred Foo,

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

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

Inoltre puoi accedere da solo, ad es. "self.HUGE" o "self.BIG". Funzionerebbe solo internamente all'interno della classe.
cevaris,

4

Espandendo la risposta di betabandido, potresti scrivere una funzione per iniettare gli attributi come costanti nel modulo:

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_BIGfuori classe sarà lo stesso? Sarà modificabile Animal.SIZE_HUGE = 'Small'?
Crusader,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.