Как предупредить об устаревании класса (имени)

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

Я думаю, что для обеспечения обратной совместимости будет достаточно использовать такой псевдоним:

class NewClsName:
    pass

OldClsName = NewClsName

Я понятия не имею, как элегантно отметить OldClsName как устаревшее. Возможно, я мог бы сделать OldClsName функцией, которая выдает предупреждение (в журналы) и создает объект NewClsName из его параметров (используя * args и * * kvargs ), но это не кажется достаточно элегантным (а может, и так?).

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

Вопрос: как предупредить пользователей об использовании устаревшего псевдонима класса (или устаревшего класса в целом).

РЕДАКТИРОВАТЬ : Функциональный подход у меня не работает (я уже попробовал), потому что в классе есть некоторые методы класса (фабричные методы), которые не могут быть вызваны, когда OldClsName определяется как функция.Следующий код не будет работать:

class NewClsName(object):
    @classmethod
    def CreateVariant1( cls, ... ):
        pass

    @classmethod
    def CreateVariant2( cls, ... ):
        pass

def OldClsName(*args, **kwargs):
    warnings.warn("The 'OldClsName' class was renamed [...]",
                  DeprecationWarning )
    return NewClsName(*args, **kwargs)

OldClsName.CreateVariant1( ... )

Из-за:

AttributeError: 'function' object has no attribute 'CreateVariant1'

Является ли наследование единственным вариантом? Честно говоря, мне это кажется не очень чистым - это влияет на иерархию классов, вводя ненужные производные. Кроме того, OldClsName не является NewClsName , что не является проблемой в большинстве случаев, но может быть проблемой в случае плохо написанного кода с использованием библиотеки.

Я мог бы также создать фиктивный, несвязанный класс OldClsName и реализовать в нем конструктор, а также оболочки для всех методов класса, но, на мой взгляд, это еще худшее решение.

43
задан James Draper 3 August 2017 в 14:25
поделиться