Як реалізувати декоратор класу в python

Питання знавцям python. Вихідне завдання - необхідно, щоб один із методів класу обертався в декоратори. Це можна зробити через перевизначення цього методу та обертанням його через method_decorator.

Я не хочу переписувати щоразу цей метод. Мені здається більш логічним таке рішення

Ось питання - як написатиviewdecorator?

Зараз я написав таке:

При цьому чомусь не переносяться classmethod-и і classonlymethod-и. Саме в моєму випадку не йде as_view(). Як зробити так, щоб це перенеслося?

Ну не можу я не запропонувати свій варіант реалізації =)

@vvpoloskin Ну цей варіант дуже створює об'єкт класу 1 раз для вюхи. У вашому випадку функція newgetattr виконували майже 3 рази т.к. від джанги йшло звернення до різних методів через getattribute до того, як зголосився dispatch.

Скопіювати метоінформацію у класі досить просто. Але саме той випадок коли гнучкість перекривається красою і доводиться вибирати або гнучкість або краса. Я вибрав би друге. =)

@abukin ваш код є більш наочний та красивий, але.

Зрештою, яка різниця, викликається мій новий метод тричі або метод вашого нового класу)

На рахунок розуміння коду іншими програмістами - їм буде смішно побачити викинутий виняток у новому класі, якого вони самі не писали)

Ще зауваження щодо метаінформації - так, ви перевизначите такі дрібниці, як __doc__, __name__. Але для подібності ще треба міняти mro і bases (а може ще й __subclasshook__?)

@vvpoloskin Не розумію навіщо ви показали розмір об'єкта, що створюється в пам'яті? Це ні на що не впливатиме тим більше на швидкість. Зараз на машинах гігабайтипам'яті. А ось непотрібний виклик функції порівняно з розмірністю уповільнить рівно *n разів.

Який викинутий виняток? Там не повинно бути жодних винятків це звичайне успадкування з перезаписом методу базового класу, тільки виконане через декоратор. До речі, програмісти постійно бачать винятки т.к. нічого не повинно замовчуватись і це нормально.

Навіщо копіювати вам bases? Яка потреба в цьому? У вас просте спадкування. Усі базові класи і так створилися у потрібному порядку. У результаті до класу в'юха просто додасться до початку визначення базових класів ще один базовий клас OverrideClass, а mro це просто функція, яка відображає базові класи.

І від цього класу успадкуєте всі свої породжені завірюхи. Наприклад:

Тільки слідкуйте за тим, щоб LoginRequiredMixin був першим базовим класом. Тому перш за все буде викликатися його dispatch, а потім вже всі інші, якщо пройдуть перевірку.

Приватні випадки можна й у нащадках тим самим декоратором продати. А взагалі та якщо потрібна гнучкість і проект із купи різних в'юх де йде перемикання функціоналу. Не бачу жодної проблеми написати 3 різні міксини і за своєю потребою їх успадковувати можна навіть в окремому додатку. Це не простирадло, а явне позначення бажаного в дійсне. Бо "Явне краще, ніж неявне. Просте краще, ніж складне."

І взагалі, якщо у вас може бути не django який там може бути dispatch? Це лише метод класу Generic Base View джанговський.