Константа класса Python с использованием метода инициализации класса?

Я создал класс, который можно сравнивать и сортировать внутри общих структур данных.

Дело в том, что я хотел сделать две константы класса для максимального и минимального значений, которые может принимать класс. Поэтому я мог бы назвать это значение, просто импортировав MyClass и написав

obj = MyClass.MY_MAX_CONSTANT

Дело в том, что вызов конструктора или метода init для инициализации этих констант не допускается.

В Java это было бы объявлено как статическое, и это сработало бы, но я не знаю, как я могу сделать константу класса/статическую в Python, используя метод конструктора/инициализации. Не нашел много поиска в Google, но некоторые общие рецепты для констант и предложения по созданию свойств.

Мне не нужен механизм, чтобы избежать изменения постоянного значения, поскольку я его точно не меняю.

Моя первая попытка была:

class MyClass(object):
    MY_MAX_CONSTANT = MyClass(10,10)
    MY_MIN_CONSTANT = MyClass(0,0)

    def __init__(self, param1, param2): # Not the exact signature, but I think this works as an example 
        # We imagine some initialization work here
        self.x = param1
        self.y = param2


    # SORT FUNCTIONS
    def __cmp__(self, other):
        # Implementation already made here

    def __eq__(self, other):
        # Implementation already made here

    def __ne__(self, other):
        # Implementation already made here

    def __ge__(self, other):
        # Implementation already made here

    # And so on...

Вторая попытка, используя некоторые функции для каждой константы:

class MyClass(object):
    def __init__(self, param1, param2): # Not the exact signature, but I think this works as an example 
        # We imagine some initialization work here
        self.x = param1
        self.y = param2
        MY_MAX_CONSTANT = None
        MY_MIN_CONSTANT = None

    @staticmethod
    def get_max(self):
        if not MyClass.MY_MAX_CONSTANT:
            MyClass.MY_MAX_CONSTANT = MyClass(10,10)
        return MyClass.MY_MAX_CONSTANT

    @staticmethod
    def get_min(self):
        if not MyClass.MY_MIN_CONSTANT:
            MyClass.MY_MIN_CONSTANT = MyClass(0,0)
        return MyClass.MY_MIN_CONSTANT    

    # SORT FUNCTIONS (I'm not writing them twice for spacing)

Но я хотел избежать странных функциональных механизмов только для создания двух констант.

Я предпочитаю постоянное присутствие в классе, а не модуль, потому что это кажется мне более естественным, но я слышу любые советы или предложения. Может ли кто-нибудь указать мне лучшее решение для Python?

Спасибо


person madtyn    schedule 26.10.2017    source источник
comment
Дело в том, что вызов конструктора или метода init для инициализации этих констант не допускается. - кто не разрешает? Ваш учитель? Python позволяет это, но вам придется создавать константы, как только класс действительно существует — он еще не существует внутри тела оператора класса.   -  person user2357112 supports Monica    schedule 26.10.2017
comment
Где я должен определить константы? Мне init не кажется подходящим местом для рекурсивного вызова самого себя.   -  person madtyn    schedule 26.10.2017


Ответы (1)


Добавьте свои константы после создания класса, вам разрешено добавлять дополнительные атрибуты класса:

class MyClass:
    # ...

MyClass.MY_MAX_CONSTANT = MyClass(10, 10)
MyClass.MY_MIN_CONSTANT = MyClass(0, 0)

Только после завершения выполнения оператора class становится доступным объект класса, привязанный к имени MyClass. Вы не можете создавать экземпляры до этого момента.

person Martijn Pieters    schedule 26.10.2017
comment
Спасибо. Это работает. Теперь я сомневаюсь только в том, как работает предложение импорта, когда я импортирую класс. Он приносит из правильного модуля все, что связано с MyClass? Как Python узнает, когда прекратить импорт? Откуда я знаю? (Пока не знаю, я думал, что импорт класса импортирует только содержимое с отступом в соответствии с объявлением) - person madtyn; 26.10.2017
comment
Импорт выполнит весь код верхнего уровня в вашем модуле в первый раз. Остальное — это просто привязка имен к объектам; sys.modules['modulename'] — это центральный объект модуля, и вы получаете имена, связанные с различными конкретными именами, которые вы можете оттуда импортировать, или просто ссылку на сам объект модуля. Так что все будет существовать в памяти. - person Martijn Pieters; 26.10.2017