Я пытаюсь найти лучший способ создать декоратор класса, который делает следующее:
- Внедряет несколько функций в украшенный класс
- Принудительно вызывает одну из этих функций ПОСЛЕ того, как декорированный класс
__init__
вызывается
В настоящее время я просто сохраняю ссылку на «оригинальный» метод __init__
и заменяю ее своим __init__
, который вызывает оригинал и мою дополнительную функцию. Это выглядит примерно так:
orig_init = cls.__init__
def new_init(self, *args, **kwargs):
"""
'Extend' wrapped class' __init__ so we can attach to all signals
automatically
"""
orig_init(self, *args, **kwargs)
self._debugSignals()
cls.__init__ = new_init
Есть ли лучший способ «дополнить» исходный __init__
или внедрить мой вызов в другое место? Все, что мне действительно нужно, это чтобы мой self._debugSignals()
вызывался через некоторое время после создания объекта. Я также хочу, чтобы это происходило автоматически, поэтому я подумал, что после __init__
будет хорошее место.
Дополнительно разное. заметки декоратора
Возможно, стоит упомянуть некоторую предысторию этого декоратора. Полный код можно найти здесь. Смысл декоратора в том, чтобы автоматически присоединяться к любым сигналам PyQt и печатать, когда они испускаются. Декоратор отлично работает, когда я украшаю свои собственные подклассы QtCore.QObject
, однако недавно я пытался автоматически декорировать все дочерние объекты QObject.
Я хотел бы иметь режим «отладки» в приложении, где я могу автоматически печатать ВСЕ сигналы, просто чтобы убедиться, что все работает так, как я ожидаю. Я уверен, что это приведет к ТОННАМ отладки, но я все равно хотел бы посмотреть, что происходит.
Проблема в том, что моя текущая версия декоратора вызывает segfault при замене QtCore.QObject.__init__
а>. Я пытался отладить это, но весь код сгенерирован SIP, с которым у меня мало опыта.
Итак, мне было интересно, есть ли более безопасный, более питонический способ внедрить вызов функции ПОСЛЕ __init__
и, надеюсь, избежать segfault.
QtCore.QObject.__init__
реализовано внутри библиотеки Qt, т.е. в C++, поэтому вы не можете просто заменить__init__
. - person rainer   schedule 15.04.2013QtCore.QObject.__init__
, но запутался во всей магии sip/C++, которая создает оболочки и т. д. Это объясняет, почему мой декоратор работает с объектами на основе Python (или, по крайней мере, с теми, которые не так тесно связаны с слой sip/С++). Однако я подумал, может быть, есть более чистый способ добиться такого поведения без перехвата__init__
, потому что мне тоже не очень нравится такое поведение для объектов на основе python. Однако «это просто работает» для объектов python. - person durden2.0   schedule 15.04.2013