【问题标题】:Organization method for handling routing between many methods处理多方法间路由的组织方法
【发布时间】:2020-12-06 17:36:47
【问题描述】:

这可能是一个见仁见智的问题,但由于我主要是自学成才,我想征求意见。我有一个输入,然后是一个路由方法,然后是处理路由的单个方法,如下所示:

# Use first char as prefix for routing.
typ_pfx =  input[0]
inb_typ_handler(typ_pfx)

#=== Routing ===#
def _inb_typ_handler(self, typ_pfx):
    try:
        typ_pfx = typ_pfx.upper()

        if typ_pfx == 'M':
            # Default. Prints to screen.
            self._m_handler()
        elif typ_pfx == 'C':
            # Incoming controller message.
            self._c_handler()
        elif typ_pfx == 'S':
            # Server messages.
            self._s_handler()
        elif typ_pfx == 'U':
            # Misc handler....
            self._u_handler()

        # ...
        # ... omitted for succinctness
        # ...

        else:
            print('Prefix: ', typ_pfx)
            print('-x- Unknown message type error.')
    except:
        pass

#=== Handlers ===#
def _m_handler(self):
    """Standard message. Unpacks message, and prints screen."""
    trim_msg = self.unpack_msg(serv_sock)
    self.print_message(trim_msg, enc=self.encrypt_traffic)

def _c_handler(self):
    """Control messages from another user. Not displayed."""
    self.unpack_msg(serv_sock)

def _s_handler(self):
    """Server announcements."""
    msg = self.unpack_msg(serv_sock).decode()
    msg = f"@YO: {msg}"
    self.print_message(msg, style_name='BLUEGREY')

# ... And so on and so forth.

现在,它们都在同一个类中,在主文件上(用于套接字客户端)。

我的第一直觉是将路由器移动到模块文件,将处理程序移动到单独的模块文件,然后import它们。

所以 inb_typ_handler 会像 socketIO 模块一样被导入,然后这些模块会进入它们自己的处理程序模块。

我想知道,有没有其他方法来处理这个问题,让它更干净或更好地组织它,因为我的处理程序和路由器的数量一直在增加,而且它目前正处于在向后滚动时很容易迷路的地步第四次。

他们使用字母作为前缀代码,但我将它们按功能分组,而不是按字母顺序。我听说过@decorators,但从未使用过它们,有什么方法可以应用它们来帮助组织我的处理程序吗?

我还能做些什么来使代码简洁易读?

【问题讨论】:

  • 您可以创建一个字典,将typ_pfx 值映射到不同的方法。这会更快,因为路由被简化为简单的字典查找操作。
  • 哦,太棒了!那么它究竟是如何工作的呢?函数 = routing_dict[typ_pfx]?如何从字典中调用函数?我也可以将参数传递给函数吗?
  • 是的,就是这个想法 - 请参阅我添加的详细答案。

标签: python code-organization project-organization


【解决方案1】:

以下是我在 cmets 中建议的实现方法(基于您的示例代码):

class Foobar:
    def inb_typ_handler(self, typ_pfx):
        handler = self.routing_dict.get(typ_pfx.upper(), type(self)._error_handler)
        handler(self, typ_pfx)

    def _m_handler(self, typ_pfx):
        """Standard message. Unpacks message, and prints screen."""
        print('In _m_handler()')

    def _c_handler(self, typ_pfx):
        """Control messages from another user. Not displayed."""
        print('In _c_handler()')

    def _s_handler(self, typ_pfx):
        """Server announcements."""
        print('In _s_handler()')

    def _error_handler(self, typ_pfx):
        raise RuntimeError(f'Unknown message type error: "{typ_pfx}"')

    routing_dict = {  # Create method routing table for class.
        'M': _m_handler,
        'C': _c_handler,
        'S': _s_handler,
    }


# Sample usage.
foobar = Foobar()
foobar.inb_typ_handler('m')
foobar.inb_typ_handler('s')
foobar.inb_typ_handler('x')    # An invalid message type.

上面例子产生的输出:

In _m_handler()
In _s_handler()
Traceback (most recent call last):
  File "routing_example.py", line 39, in <module>
    foobar.inb_typ_handler('x')
  File "routing_example.py", line 9, in inb_typ_handler
    handler(self, typ_pfx)
  File "routing_example.py", line 24, in _error_handler
    raise RuntimeError(f'Unknown message type error: "{typ_pfx}"')
RuntimeError: Unknown message type error: "x"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-04
    • 2021-12-18
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多