Константи класу в пітоні


129

У python я хочу, щоб у класу були деякі "константи" (практично, змінні), які будуть загальними у всіх підкласах. Чи є спосіб це зробити з дружнім синтаксисом? Зараз я використовую:

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

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

і мені цікаво, чи є кращий спосіб зробити це чи спосіб це зробити, без того, щоб писати "Тварина". перед розмірами. Дякую! редагувати: забув згадати, що кінь успадковує від тварин.


16
Не повна відповідь, але якщо SIZESніколи не змінюється, обов'язково використовуйте кортеж замість списку. Так("Huge","Big","Medium","Small")
jamylak

Схоже, ви насправді переслідуєте тут
Ерік

Відповіді:


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"] я повинен використовувати цей тип константи.
Lova Chittumuri

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)

Також ви можете отримати доступ через себе, наприклад. "self.HUGE" або "self.BIG". Це буде працювати лише всередині класу.
cevaris

4

Розгортаючи відповідь бетабандідо, ви можете написати функцію для введення атрибутів як констант у модуль:

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'?
хрестоносець
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.