«METHODNAME» в качестве метода Client по сравнению с irc_'METHODNAME 'в витой - PullRequest
1 голос
/ 01 июля 2010

Глядя на twisted.words.protocols.irc.IRCClient, мне кажется, что есть несколько странно избыточных методов. Например, есть метод «privmsg», но также есть метод «irc_PRIVMSG»

В качестве другого примера рассмотрим 'join' и 'irc_JOIN'

То, что я хочу знать, это то, почему избыточность, это всего лишь два примера из многих. Используются ли два разных типа в разных контекстах? Мы должны использовать один тип, а не другой?

1 Ответ

4 голосов
/ 01 июля 2010

Вы на правильном пути в отношении двух разных типов методов, используемых в разных контекстах.На самом деле это легко увидеть, изучив способ обработки 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, если хотите - я обычно нахожу это полезным, поскольку это облегчает модульное тестирование и сохраняет логику разбора протокола отдельно от логики приложения - но этодо вас.

...