Форум сайта python.su
0
Есть проект, в котором реализована работа с events. Типов событий довольно много, и каждое событие может иметь цепочку обработчиков.
Благодаря переопределению __iadd__ , обработчики добавляются очень просто: Event += newhandler
У меня есть возможность редактировать код лишь некоторых обработчиков событий, и я хочу добавить вызов своих процедур/функций к другим событиям.
В том месте кода, где я имею возможность править исходник, я написал:
def myHandler():
print "now i got a machine gun!"
targetEvent += myHandler
set([
<function myHandler at 0x0FE3F230>,
<function myHandler at 0x12122DF0>,
<function myHandler at 0x0FE3FEB0>,
<function myHandler at 0x0FE3FEF0>,
...еще много раз ...
<function myHandler at 0x0FE12370>])
if myHandler in targetEvent._eventHandlers_:
pass
else:
targetEvent += myHandler
Офлайн
20
> так как редактируемый мною обработчик в котором я добавляю свой хэндлер, вызывается несколько раз,
> получается, что у targetEvent вырастает список обработчиков
Как так получается я не понял. Зачем переопределять одну и ту же функцию, делающую одно и то же и подписывать на одно и тоже событие? Это, кстати, ещё и умудриться надо:
for i in range(5):
def handler():
print 'я дурак'
myevent += handler
Отредактировано (Ноя. 9, 2011 03:38:02)
Офлайн
0
Дело в том, что другого способа у меня нет. Только из нескольких событий, которые могут вызываться несколько раз в течение работы программы, соответственно, надо иметь проверки на уникальность.
Офлайн
20
Пример в студию.
И не кусок вырвиглазного кода, а нормальный, модуль или пакет. Такой что бы работал и претензии были только по твоей теме.
А по сути:
>> так как редактируемый мною обработчик в котором я добавляю свой хэндлер, вызывается несколько раз,
>> получается, что у targetEvent вырастает список обработчиков
> Как так получается я не понял. Зачем переопределять одну и ту же функцию, делающую одно и то же и
> подписывать на одно и тоже событие?
> Вообще, если есть вероятность многократной подписки на одно и тоже событие обработчика, который
> должен быть подписан только раз, то что то в коде не так, и желаемая проверка это плохой способ справить
> с проблемой.
Никаких объяснений и возражений не последовало, так что я вряд ли в силе помочь, не мой, похоже, уровень.
..bw
Офлайн
13
Тут трудно что-либо сказать не зная как реализован __iadd__ у targetEvent. Можете показать код или хотя бы рассказать как это сделано? По сути нужно либо сделать так, чтобы сам __iadd__ не добавлял, либо не добавлять, поняв, что targetEvent уже содержит наш обработчик. В обоих случаях нужны хоть какие-то сведения о targetEvent. Пока вы их не дадите вам никто не поможет.
Офлайн
0
вот реализация event-ов.
class Event(object):
def __init__(self, manager=None):
self._Event__delegates = set()
if manager is not None:
manager.register(self)
return None
def __call__(self, *args):
except:
LOG_CURRENT_EXCEPTION()
continue
for delegate in set(self._Event__delegates):
delegate(*args)
continue
def __iadd__(self, delegate):
self._Event__delegates.add(delegate)
return self
def __isub__(self, delegate):
self._Event__delegates.discard(delegate)
return self
def clear(self):
self._Event__delegates.clear()
if str(repr(targetEvent._Event__delegates)).find('myHandler')>-1:
#хук уже есть
pass
else:
targetEvent += myHandlerОфлайн