Constantes de classe em python


128

Em python, eu quero que uma classe tenha algumas "constantes" (praticamente variáveis) que serão comuns em todas as subclasses. Existe uma maneira de fazer isso com sintaxe amigável? Agora eu uso:

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

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

e estou me perguntando se existe uma maneira melhor de fazê-lo ou uma maneira de fazê-lo sem ter que escrever "Animal". antes dos tamanhos. Obrigado! editar: esqueceu de mencionar que o cavalo herda de animal.


16
Não é uma resposta completa, mas se SIZESnunca mudar, use definitivamente uma tupla em vez de uma lista. Como assim("Huge","Big","Medium","Small")
jamylak 20/05

Parece que você está realmente depois de uma enumeração aqui
Eric

Respostas:


141

Como Horseé uma subclasse de Animal, você pode simplesmente mudar

print(Animal.SIZES[1])

com

print(self.SIZES[1])

Ainda assim, você deve se lembrar que SIZES[1]significa "grande", então provavelmente você pode melhorar seu código fazendo 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)

Alternativamente, você pode criar classes intermediárias: HugeAnimal, BigAnimale assim por diante. Isso seria especialmente útil se cada classe de animais contiver uma lógica diferente.


SIZE_BIG = ["BigOne", "BigTwo"] devo usar esse tipo de constante.
Lova Chittumuri 13/08/19

17

Você pode acessá-lo SIZESpor meio de self.SIZES(em um método de instância) ou cls.SIZES(em um método de classe).

De qualquer forma, você terá que ser explícito sobre onde encontrar SIZES. Uma alternativa é colocar SIZESo módulo que contém as classes, mas você precisa definir todas as classes em um único módulo.


Cavalo é de fato uma subclasse de Animal. Na verdade, é perfeitamente possível usar self.SIZES [1] em vez de Animal.SIZES [1].
Betabandido 20/05

@betabandido: o OP corrigiu a pergunta. Atualizará a resposta de acordo.
Fred Foo

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

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

Além disso, você pode acessar via auto, ex. "self.HUGE" ou "self.BIG". Isso funcionaria apenas internamente dentro da classe.
Cevaris

4

Expandindo a resposta do betabandido, você pode escrever uma função para injetar os atributos como constantes no 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_BIGfora da aula será o mesmo? Será editável Animal.SIZE_HUGE = 'Small'?
Crusader
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.