"METHODNAME"作为客户端方法,而irc_"METHODNAME"作为扭曲方法 [英] 'METHODNAME' as Client method versus irc_'METHODNAME' in twisted

查看:92
本文介绍了"METHODNAME"作为客户端方法,而irc_"METHODNAME"作为扭曲方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看着twisted.words.protocols.irc.IRCClient,在我看来好像有些奇怪的冗余方法.例如,有一个方法"privmsg",但也有一个方法"irc_PRIVMSG"

Looking at twisted.words.protocols.irc.IRCClient, it seems to me like there are some strangely redundant methods. For instance, there is a method 'privmsg' but also a method 'irc_PRIVMSG'

作为另一个示例,考虑"join"和"irc_JOIN"

As another example consider 'join' and 'irc_JOIN'

我想知道的是为什么会有冗余,这只是很多冗余中的两个例子.两种不同的类型是否在不同的上下文中使用?我们应该使用一种而不是另一种吗?

What I want to know is why the redundancy, those are just two examples of many. Are the two different types used in different contexts? Are we supposed to use one type and not another?

推荐答案

您正在正确地了解在不同上下文中使用的两种不同类型的方法.通过检查IRCClient处理接收到的数据的方式,实际上可以很容易地看出这一点.首先,将它们解析为几行,然后将其拆分,并将片段传递给其自己的handleCommand方法:

You're on the right track about the two different types of methods being used in different contexts. This can actually be seen quite easily by examining the way IRCClient handles data it receives. First it parses them into lines, then it splits the lines up and passes the pieces to its own handleCommand method:

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查找该方法.如果找到,它将被调用.

This is an example of a pattern that's quite common in Twisted protocol implementations and, even more generally, in Python programs as a whole. Some piece of the input is used to construct a method name dynamically. Then getattr is used to look up that method. If it is found, it is called.

由于服务器正在发送"PRIVMSG ..."和"JOIN ..."之类的客户端行,因此导致IRCClient查找诸如irc_PRIVMSGirc_JOIN之类的方法.

Since the server is sending the client lines like "PRIVMSG ..." and "JOIN ...", this results in IRCClient looking up methods like irc_PRIVMSG and irc_JOIN.

这些irc_*方法仅在拆分后调用,否则在行的其余部分未解析.这提供了消息附带的所有信息,但并非始终是存储数据的最佳格式.例如,JOIN消息包括包含主机掩码的用户名,但主机掩码通常是无关紧要的,而仅是昵称是理想的.因此,JOIN所做的事情对于irc_*方法来说是相当典型的:它将粗略的数据转换为使用起来更令人愉快的东西,并将结果传递给userJoined:

These irc_* methods are just called with the split up but otherwise unparsed remainder of the line. This provides all of the information that came with the message, but it's not always the nicest format for the data to be in. For example, JOIN messages include usernames that include a hostmask, but often the hostmask is irrelevant and only the nickname is desired. So JOIN does something that's fairly typical for irc_* methods: it turns the rough data into something more pleasant to work with and passes the result on to 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.这是从低级数据到应为应用程序开发人员使用的更方便的转换的另一个示例.

You can see that there's also a conditional here, sometimes it calls joined instead of userJoined. This is another example of a transformation from the low-level data into something which is supposed to be more convenient for the application developer to work with.

此分层应该可以帮助您确定在处理事件时要覆盖的方法.如果最高级别的回调(例如userJoinedjoinedprivmsg)足以满足您的要求,则应使用这些回调,因为它们会使您的工作最容易.另一方面,如果它们以不方便的格式显示数据或不方便以其他方式使用,则可以降至irc_*级别.您的方法将被调用,而不是在IRCClient上定义的方法,因此您可以使用较低级别的格式处理数据,甚至不会调用较高级别的回调(除非您在覆盖时也调用了基本实现)方法).

This layering should help you decide which methods to override when handling events. If the highest level callback, such as userJoined, joined, or privmsg is sufficient for your requirements, then you should use those because they'll make your task the easiest. On the other hand, if they present the data in an inconvenient format or are awkward to use in some other way, you can drop down to the irc_* level. Your method will be called instead of the one defined on IRCClient, so you can handle the data in the lower-level format and the higher level callback won't even be invoked (unless you also invoke the base implementation when you override the method).

您还将发现有些IRCClient甚至没有为其定义irc_*方法的IRC消息.正如我们在上面的handleCommand方法中所看到的,所有这些都转到了irc_unknown回调中.但是,如果在IRCClient子类上定义了irc_*方法,则handleCommand将开始将数据传递给该方法.显然,在这些情况下,唯一的选择是定义irc_*方法,因为没有更高级别的回调(例如irc_PRIVMSG/privmsg情况下的privmsg).

You'll also find there are IRC messages which IRCClient doesn't even define an irc_* method for. As we saw above in the handleCommand method, these all go to the irc_unknown callback. But if you define an irc_* method on your IRCClient subclass, then handleCommand will start passing the data to that method. Clearly in these cases, your only choice is to define the irc_* method, since there is no higher-level callback (like privmsg in the irc_PRIVMSG/privmsg case).

如果愿意,您可以类似于IRCClient的方式来构造irc_*方法的实现-我通常会发现这样做很有帮助,因为它使单元测试更加容易,并使协议解析逻辑与应用程序逻辑-但这取决于您.

You can structure your implementations of irc_* methods similarly to the way IRCClient does, if you like - I usually find it helpful to do so, since it makes unit testing easier and keeps the protocol parsing logic separate from the application logic - but it's up to you.

这篇关于"METHODNAME"作为客户端方法,而irc_"METHODNAME"作为扭曲方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆