2012-05-20 17 views
66

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

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 quindi dover scrivere "Animal". prima delle taglie. Grazie! modifica: ho dimenticato di menzionare che il cavallo eredita dall'animale.

+9

Non è una risposta completa, ma se 'SIZES' non cambia mai, sicuramente utilizzare una tupla invece di una lista . Mi piace così '(" Enorme "," Grande "," Medio "," Piccolo ")' – jamylak

+0

Sembra che tu sia davvero dopo un enum qui – Eric

risposta

12

È possibile ottenere SIZES tramite self.SIZES (in un metodo di istanza) o cls.SIZES (in un metodo di classe).

In ogni caso, sarà necessario essere espliciti su dove trovare SIZES. Un'alternativa è inserire SIZES nel modulo che contiene le classi, ma è necessario definire tutte le classi in un singolo modulo.

+0

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

+0

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

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

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

Anche tu puoi accedere da solo, es. "self.HUGE" o "self.BIG". Questo funzionerebbe solo all'interno della classe. – cevaris

82

Dal Horse è una sottoclasse di Animal, si può semplicemente cambiare

print(Animal.SIZES[1]) 

con

print(self.SIZES[1]) 

Ancora, è necessario ricordare che SIZES[1] significa "grande", quindi probabilmente potrebbe 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.

2

Ampliando la risposta di betabandido, si potrebbe 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 
+0

'print SIZE_BIG' fuori dalla classe sarà lo stesso? Sarà modificabile 'Animal.SIZE_HUGE = 'Small''? – Crusader