Вы на правильном пути в отношении двух разных типов методов, используемых в разных контекстах.На самом деле это легко увидеть, изучив способ обработки 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()
Это пример шаблона, который довольно распространен в реализациях Twisted протокола, и,даже более широко, в программах на 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
, поэтому вы можете обрабатывать данные в формате более низкого уровня, и обратный вызов более высокого уровня даже не будет вызываться (если только вы не вызовете базовую реализацию при переопределенииmethod).
Вы также найдете сообщения IRC, для которых IRCClient
даже не определяет метод irc_*
.Как мы видели выше в методе handleCommand
, все они идут к обратному вызову irc_unknown
.Но если вы определите метод irc_*
в своем подклассе IRCClient
, то handleCommand
начнет передавать данные этому методу.Очевидно, что в этих случаях ваш единственный выбор - определить метод irc_*
, поскольку нет обратного вызова более высокого уровня (например, privmsg
в случае irc_PRIVMSG
/ privmsg
).
Вы можетеструктурируйте свои реализации методов irc_*
аналогично тому, как это делает IRCClient
, если хотите - я обычно нахожу это полезным, поскольку это облегчает модульное тестирование и сохраняет логику разбора протокола отдельно от логики приложения - но этодо вас.