Константы классов в Python

129

В Python я хочу, чтобы у класса были некоторые «константы» (фактически, переменные), которые будут общими для всех подклассов. Есть ли способ сделать это с помощью понятного синтаксиса? Сейчас использую:

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

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

и мне интересно, есть ли лучший способ сделать это или способ сделать это без необходимости писать «Животное». перед размерами. Спасибо! edit: забыл упомянуть, что лошадь наследуется от животного.

nodwj
источник
16
Не полный ответ, но если SIZESникогда не меняется, определенно используйте кортеж вместо списка. Вроде так("Huge","Big","Medium","Small")
джамылак
Похоже, вы действительно хотите перечислить здесь
Эрик

Ответы:

141

Поскольку Horseэто подкласс Animal, вы можете просто изменить

print(Animal.SIZES[1])

с участием

print(self.SIZES[1])

Тем не менее, вы должны помнить, что это SIZES[1]означает «большой», поэтому, вероятно, вы могли бы улучшить свой код, сделав что-то вроде:

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

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

Кроме того , вы можете создать промежуточные классы: HugeAnimal, BigAnimal, и так далее. Это будет особенно полезно, если каждый класс животных будет содержать разную логику.

betabandido
источник
SIZE_BIG = ["BigOne", "BigTwo"] должен ли я использовать этот тип константы.
Лова Читтумури
18

Вы можете получить доступ SIZESс помощью self.SIZES(в методе экземпляра) или cls.SIZES(в методе класса).

В любом случае вам нужно будет четко указать, где искать SIZES. Альтернативой является установка SIZESмодуля, содержащего классы, но тогда вам нужно определить все классы в одном модуле.

Фред Фу
источник
Лошадь действительно является подклассом животных. На самом деле вполне возможно использовать self.SIZES [1] вместо Animal.SIZES [1].
betabandido
@betabandido: ОП исправил вопрос. Обновим ответ соответственно.
Фред Фу
12
class Animal:
    HUGE = "Huge"
    BIG = "Big"

class Horse:
    def printSize(self):
        print(Animal.HUGE)
Амит
источник
Также вы можете получить доступ через себя, например. "Я. ОГРОМНЫЙ" или "Я БОЛЬШОЙ". Это будет работать только внутри класса.
cevaris 08
4

Расширяя ответ betabandido, вы можете написать функцию для вставки атрибутов в виде констант в модуль:

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_BIGвне класса будет то же самое? Будет ли он доступен для редактирования Animal.SIZE_HUGE = 'Small'?
Crusader