Python 调用函数和被调用函数之间的函数间通信
我想知道是否有一种干净的方法可以在调用函数/方法和被调用函数/方法之间建立某种通信。比方说,调用方是主驱动程序的一部分,主驱动程序在UI上显示当前应用程序状态。它需要连接到远程网络节点,并为此调用另一个Python模块中的另一个方法(在同一线程中) 主(驱动)模块:Python 调用函数和被调用函数之间的函数间通信,python,function,methods,communication,messaging,Python,Function,Methods,Communication,Messaging,我想知道是否有一种干净的方法可以在调用函数/方法和被调用函数/方法之间建立某种通信。比方说,调用方是主驱动程序的一部分,主驱动程序在UI上显示当前应用程序状态。它需要连接到远程网络节点,并为此调用另一个Python模块中的另一个方法(在同一线程中) 主(驱动)模块: import ssh_client node_ip = "10.10.10.10" node_user = "myuser" node_pass = "mypass" conn_result = False while not
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...
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
ssh\u客户端模块:
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...
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方法时需要数据。换句话说,当出现异常时,我希望connect方法告诉驱动程序模块发生异常并尝试重新连接
虽然可以通过粗糙的方法实现这一点,比如将状态更新为文本文件,并让调用者轮询状态更改,但这听起来不是一个非常令人信服的解决方案。Python中是否有任何东西可以在这里证明是方便的,我是否遗漏了一些明显的东西?解决这个问题的好方法是什么?一个非常幼稚的方法是这样的:
from threading import Thread
from Queue import Queue
def connect(queue, *args):
retries_left = 3
while retries_left > 0:
try:
your_connect_call(*args)
except Exception:
queue.put('Error')
retries_left -= 1
# Send poison pill to notify the caller that the task is complete
queue.put(None)
return False
def caller():
q = Queue()
t = Thread(target=connect, args=(q,))
t.start()
while True:
msg = q.get()
if msg is None:
break
print(msg)
res = t.join()
return res
调用者启动一个单独的线程,并将
队列
传递给被调用的方法。被调用的方法用状态通知填充队列
,调用者可以对此做出反应(这里它只是打印这些消息)。被调用的方法通过发送None
信号通知调用方不再需要消息。调用方等待该信号,然后等待该方法返回。一种非常简单的方法如下:
from threading import Thread
from Queue import Queue
def connect(queue, *args):
retries_left = 3
while retries_left > 0:
try:
your_connect_call(*args)
except Exception:
queue.put('Error')
retries_left -= 1
# Send poison pill to notify the caller that the task is complete
queue.put(None)
return False
def caller():
q = Queue()
t = Thread(target=connect, args=(q,))
t.start()
while True:
msg = q.get()
if msg is None:
break
print(msg)
res = t.join()
return res
调用者启动一个单独的线程,并将
队列
传递给被调用的方法。被调用的方法用状态通知填充队列
,调用者可以对此做出反应(这里它只是打印这些消息)。被调用的方法通过发送None
信号通知调用方不再需要消息。调用者等待该信号,然后等待方法返回。是否让调用者负责重试连接?对我来说,这似乎是更干净的解决办法connect
会让异常冒泡到调用方。不幸的是,否,我希望网络模块负责所有重新连接,并让调用方只负责调用任务。不幸的是,您无法像计划中那样执行此操作,尤其是在一个线程中。任何类型的信息都会在堆栈中向下发送,直到接收器再次位于堆栈顶部时才会进行处理。这意味着被调用函数必须首先返回(或以任何方式终止)。堆栈中不同位置上的任何两个函数都不能同时运行代码。如果调用方对通知做出反应,则必须在单独的线程或进程中异步调用connect
。另一种方法是使用异步franework。有一些,只有两个名称:asyncio和Twisted。让调用方负责重试连接是一个选项吗?对我来说,这似乎是更干净的解决办法connect
会让异常冒泡到调用方。不幸的是,否,我希望网络模块负责所有重新连接,并让调用方只负责调用任务。不幸的是,您无法像计划中那样执行此操作,尤其是在一个线程中。任何类型的信息都会在堆栈中向下发送,直到接收器再次位于堆栈顶部时才会进行处理。这意味着被调用函数必须首先返回(或以任何方式终止)。堆栈中不同位置上的任何两个函数都不能同时运行代码。如果调用方对通知做出反应,则必须在单独的线程或进程中异步调用connect
。另一种方法是使用异步franework。有一些,只有两个名字:asyncio和Twisted。这肯定可以工作,但我真的很期待在不涉及线程的情况下完成它。无论如何,我都会尝试一下,谢谢。这肯定会奏效,但我真的很期待在不进入线程的情况下完成它。无论如何我都会试试这个,谢谢。