Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Twisted中分离协议的两个不同阶段?_Python_Twisted - Fatal编程技术网

Python 如何在Twisted中分离协议的两个不同阶段?

Python 如何在Twisted中分离协议的两个不同阶段?,python,twisted,Python,Twisted,我正在尝试学习如何使用Twisted进行通信,我有点被一个概念所束缚:制定一个协议,基本上分两个阶段进行通信:首先是短握手和身份验证,然后是实际工作 我天真的做法是编写如下协议: def stringReceived(self, data): if self.state == "authenticate": handle_auth(data) else: handle_actual_work(data) def stringReceived(se

我正在尝试学习如何使用Twisted进行通信,我有点被一个概念所束缚:制定一个协议,基本上分两个阶段进行通信:首先是短握手和身份验证,然后是实际工作

我天真的做法是编写如下协议:

def stringReceived(self, data):
    if self.state == "authenticate":
        handle_auth(data)
    else:
        handle_actual_work(data)
def stringReceived(self, data):
    getattr(self, "stringReceived_{}".format(self.state))(data)

def stringReceived_authenticate(self, data):
    if self.auth_ok(data):
       self.state = 'normal'
    else:
       self.transport.loseConnection()

def stringReceived_normal(self, data):
    self.do_stuff(data)
我很难想出这种扭曲的方式。以上情况正常吗?在我看来,编写一个进行身份验证的协议和另一个只处理经过身份验证的客户机的协议更有意义,但我究竟应该如何做呢


我看了类似的问题。这里给出的解决方案基本上与我目前的方法相同。这真的是正确的方法吗?

是的,你的版本很正常。可以说Twisted应该对状态机有更多的支持,因为对于不同的协议、不同的事件星座等,Twisted内部有大约100种这种通用模式的不同实现。但这一部分本身并不是Twisted的工作:Twisted将您的对象暴露在网络中,并且将对其调用方法(在本例中,
stringReceived
)。您如何处理该消息完全取决于您的对象,而
if
语句处理该消息是完全合理的:)

在这个层次上,问题并不是关于“扭曲的方式”,而是关于状态机和依赖于上下文的方法的更好的Python习惯用法。根据协议的具体需要,您当前的方法可能很好,或者您可能希望分派到具有特殊名称的方法,如下所示:

def stringReceived(self, data):
    if self.state == "authenticate":
        handle_auth(data)
    else:
        handle_actual_work(data)
def stringReceived(self, data):
    getattr(self, "stringReceived_{}".format(self.state))(data)

def stringReceived_authenticate(self, data):
    if self.auth_ok(data):
       self.state = 'normal'
    else:
       self.transport.loseConnection()

def stringReceived_normal(self, data):
    self.do_stuff(data)

。。。或者更喜欢装饰,你可能想使用装饰,元类,或者其他完全不同的东西。这些方法都没有什么问题。

作为twisted的新手,我很难知道什么时候我遗漏了一些重要的twisted习惯用法,而不是像你所说的那样仅仅停留在python的地盘上。这就是为什么让有经验的人加入可以是一种享受。谢谢为什么要将函数名存储为字符串并执行所有额外的工作?为什么不将处理数据的函数存储在
self.state
,然后执行
self.state(data)