Уведомления

Группа в Telegram: @pythonsu

#1 Июль 28, 2015 23:17:10

py_beginner
Зарегистрирован: 2015-07-28
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Наследование от декорированого класса

Здравствуйте, уважаемые знатоки Python (Python3)! Помогите пожалуйста разобраться. Я недавно увлекся этим языком (пришел с шарпа) и столкнулся с ситуацией на которой уже сломал моск.

Есть кусочек кода, на первый взгляд ничего сложного, но он не отрабатывает и я не могу понять в чем дело. Суть в том, что я не могу унаследоваться от декорированого класса. Ошибка вываливается еще на этапе импорта файла, т.к. в конструктор декоратора который должен принять объект класса(производный от type) на этом этапе передается 4-е параметра вместо одного законного.

class Decorator:
def __init__(self, cls):
self.cls = cls

def __call__(self, *args, **kwargs):
return self.cls(*args, **kwargs)

@Decorator
class Parent: pass

class Child(Parent): pass

def main():
pass

if __name__ == "__main__":
main()

Я так понимаю он пытается создать метакласс раз передает ему 4-е параметра? Как обойти это ограничение? Как сделать это по-человечески? Объясните пожалуйста. Заранее благодарю!

Офлайн

#2 Июль 29, 2015 02:30:35

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Наследование от декорированого класса

py_beginner
т.к. в конструктор декоратора который должен принять объект класса
__init__ - это не конструктор, а инициализатор (когда он срабатывает, объект уже создан)
__new__ - конструктор

После декорирования Parent становится объектом, а не классом.

>>> class Decorator:
...     def __init__(self, cls):
...         self.cls = cls
...     
...     def __call__(self, *args, **kwargs):
...         return self.cls(*args, **kwargs)
... 
>>> @Decorator
... class Parent: pass
... 
>>> Parent
<__main__.Decorator object at 0xb73bf06c>
>>> Decorator
<class '__main__.Decorator'>
>>>

Соответственно, Child пытается унаследоваться от объекта.



Отредактировано py.user.next (Июль 29, 2015 02:31:10)

Офлайн

#3 Июль 29, 2015 10:29:01

py_beginner
Зарегистрирован: 2015-07-28
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Наследование от декорированого класса

Спасибо. Действительно, я забыл что декораторы это не подобие атрибутов в шарпе или аннотаций в джаве, а синтаксический сахар после применения которого объявление класса превратится в нечто вроде Parent = Decorator(Parent). Этот код - упрощенная версия декоратора который применялся для того чтобы сделать все методы класса потокобезопасными, а унаследовавшись от него планировалось избежать применения декоратора, но как оказалось достигнуть этого можно только либо декорируя наследника, а не предка, либо - реализовать нужный функционал на основе метакласса (в этом случае, по идее, проблем с наследованием возникнуть не должно). Еще раз спасибо!

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version