【发布时间】:2015-09-03 11:42:05
【问题描述】:
我在通过函数调用保持上下文管理器打开时遇到了一些问题。这就是我的意思:
在一个模块中定义了一个上下文管理器,我用它来打开与网络设备的 SSH 连接。 “设置”代码处理打开 SSH 会话并处理任何问题,而拆卸代码处理正常关闭 SSH 会话。我一般是这样使用的:
from manager import manager
def do_stuff(device):
with manager(device) as conn:
output = conn.send_command("show ip route")
#process output...
return processed_output
为了保持 SSH 会话打开并且不必在函数调用之间重新建立它,我想向“do_stuff”添加一个参数,它可以选择返回 SSH 会话以及从 SSH 返回的数据会话,如下:
def do_stuff(device, return_handle=False):
with manager(device) as conn:
output = conn.send_command("show ip route")
#process output...
if return_handle:
return (processed_output, conn)
else:
return processed_output
我希望能够从另一个函数调用此函数“do_stuff”,如下所示,这样它会向“do_stuff”发出信号,告知 SSH 句柄应与输出一起返回。
def do_more_stuff(device):
data, conn = do_stuff(device, return_handle=True)
output = conn.send_command("show users")
#process output...
return processed_output
但是我遇到的问题是 SSH 会话已关闭,这是由于 do_stuff 函数“返回”并触发了上下文管理器中的拆卸代码(这会优雅地关闭 SSH 会话)。
我尝试将“do_stuff”转换为生成器,使其状态暂停,并可能导致上下文管理器保持打开状态:
def do_stuff(device, return_handle=False):
with manager(device) as conn:
output = conn.send_command("show ip route")
#process output...
if return_handle:
yield (processed_output, conn)
else:
yield processed_output
这样称呼它:
def do_more_stuff(device):
gen = do_stuff(device, return_handle=True)
data, conn = next(gen)
output = conn.send_command("show users")
#process output...
return processed_output
但是这种方法在我的情况下似乎不起作用,因为上下文管理器被关闭,我得到一个关闭的套接字。
有没有更好的方法来解决这个问题?也许我的生成器需要更多的工作......我认为使用生成器来保持状态是我想到的最“明显”的方式,但总的来说,我是否应该研究另一种在函数调用之间保持会话打开的方式?
谢谢
【问题讨论】:
标签: python ssh network-programming paramiko contextmanager