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


129

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

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

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

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


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, и так далее. Это будет особенно полезно, если каждый класс животных будет содержать разную логику.


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.