Вы находитесь на правильном пути о двух разных типах методов, используемых в разных контекстах. Это можно увидеть довольно легко, исследуя способ, которым IRCClient
обрабатывает полученные данные. Сначала он разбирает их в линию, то она разбивает линию вверх и передает части к своему handleCommand
методы:
def handleCommand(self, command, prefix, params):
"""Determine the function to call for the given command and call
it with the given arguments.
"""
method = getattr(self, "irc_%s" % command, None)
try:
if method is not None:
method(prefix, params)
else:
self.irc_unknown(prefix, command, params)
except:
log.deferr()
Это пример узора, который довольно часто в реализации витого протокола и даже в более общем плане, в программах Python в целом. Некоторая часть ввода используется для динамического построения имени метода. Затем для поиска этого метода используется getattr
. Если он найден, он вызывается.
Поскольку сервер отправляет клиентские строки типа «PRIVMSG ...» и «JOIN ...», это приводит к IRCClient
отрываясь методы, как irc_PRIVMSG
и irc_JOIN
.
Эти методы irc_*
только что вызывается с разрывом, но в остальном не просматривается остаток строки. Это обеспечивает всю информацию, которая поступает с сообщением, но это не всегда самый приятный формат для данных. Например, сообщения JOIN
включают имена пользователей, которые включают в себя маску хоста, но часто маска хоста не имеет значения и требуется только псевдоним , Так JOIN
делает то, что это довольно типично для irc_*
методов: он превращает грубые данные в чем-то более приятным для работы и передает результат на к userJoined
:
def irc_JOIN(self, prefix, params):
"""
Called when a user joins a channel.
"""
nick = string.split(prefix,'!')[0]
channel = params[-1]
if nick == self.nickname:
self.joined(channel)
else:
self.userJoined(nick, channel)
Вы можете видеть, что есть также условно здесь, иногда звонки joined
вместо userJoined
. Это еще один пример перехода от низкоуровневых данных во что-то, что должно быть более удобным для разработчика приложений.
Это расслоение должно помочь вам решить, какие методы следует переопределять при обработке событий. Если для ваших требований достаточно обратного вызова самого высокого уровня, такого как userJoined
, joined
или privmsg
, то вы должны использовать их, потому что они упростят вашу задачу. С другой стороны, если они представляют данные в неудобном формате или неудобно использовать каким-либо другим способом, вы можете опуститься до уровня irc_*
. Ваш метод будет вызываться вместо имени, определенного на IRCClient
, поэтому вы можете обрабатывать данные в формате более низкого уровня, и обратный вызов более высокого уровня даже не будет вызываться (если вы также не вызываете базовую реализацию при переопределении метода) ,
Вы также найдете сообщения IRC, которые IRCClient
даже не определяет способ irc_*
для. Как мы видели выше в методе handleCommand
, все они переходят на обратный вызов irc_unknown
. Но если вы определяете метод irc_*
в своем подклассе IRCClient
, то handleCommand
начнет передавать данные этому методу.Ясно, что в этих случаях ваш единственный выбор - определить метод irc_*
, так как нет обратного вызова более высокого уровня (например, privmsg
в случае irc_PRIVMSG
/privmsg
).
Вы можете структурировать реализацию irc_*
методов аналогично тому, как IRCClient
делает, если вы хотите - я обычно нахожу это полезно делать, так как это делает блок тестирования проще и сохраняет синтаксический логический протокол отдельно от логики приложения - но это зависит от вас.