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

我想知道是否有一种干净的方法可以在调用函数/方法和被调用函数/方法之间建立某种通信。比方说,调用方是主驱动程序的一部分,主驱动程序在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...
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。这肯定可以工作,但我真的很期待在不涉及线程的情况下完成它。无论如何,我都会尝试一下,谢谢。这肯定会奏效,但我真的很期待在不进入线程的情况下完成它。无论如何我都会试试这个,谢谢。