【发布时间】:2016-01-01 20:00:12
【问题描述】:
我想知道是否有一种干净的方法可以在调用函数/方法和被调用函数/方法之间建立某种通信。比如说,调用者是主驱动程序的一部分,它在 UI 上显示当前应用程序状态。它需要连接到远程网络节点,为此它调用驻留在另一个 Python 模块中的另一个方法(在同一个线程中)。
主(驱动)模块:
import ssh_client
node_ip = "10.10.10.10"
node_user = "myuser"
node_pass = "mypass"
conn_result = False
while not conn_result :
conn_result = ssh_client.connect(node_ip, node_user, node_pass)
# process custom return codes from connect method here...
ssh_client 模块:
import paramiko
def connect(node_ip, node_user, node_pass):
retries_left = 3
while retries_left > 0:
try:
paramiko.SSHClient().connect(node_ip, username=node_user, password=node_pass)
return True
except Exception:
retries_left -= 1
return False
现在,网络模块方法在尝试连接时,可能会遇到网络延迟或其他问题导致的各种问题,并会相应地重试连接。此时,我希望该方法以某种方式通知我的主调用方方法连接失败并且正在尝试重新连接。
在上面的例子中,我是根据返回码来获取当前的连接情况。但是,我不依赖返回码,而是希望在连接方法执行时 的数据。换句话说,当出现异常时,我希望 connect 方法告诉驱动模块告诉驱动模块出现异常并尝试重新连接。
虽然可以通过粗略的方法来实现这一点,例如将状态更新到文本文件并让调用者轮询它以了解状态变化,但这听起来并不是一个非常有说服力的解决方案。 Python中有什么东西可以在这里证明很方便,我是否遗漏了一些明显的东西?解决这个问题的好方法是什么?
【问题讨论】:
-
是否让调用者负责重试连接是一种选择?这对我来说似乎是更清洁的解决方案。
connect然后只会让异常冒泡给调用者。 -
很遗憾,不,我希望网络模块负责所有重新连接,让调用者只负责调用任务。
-
不幸的是,你不能像你计划的那样去做,尤其是不能在一个线程中。任何类型的信息都被发送到堆栈中,直到接收者再次位于堆栈顶部才被处理。这意味着被调用的函数必须首先返回(或以任何方式终止)。堆栈中不同位置的两个函数不能同时运行代码。
-
如果您的调用者应对通知做出反应,您必须在单独的线程或进程中异步调用
connect。 -
另一种可能是使用异步框架。有一些,只有两个名称:asyncio 和 Twisted。
标签: python function methods communication messaging