嗨,我想知道如何在课程之间传递对象.我将使用我的脚本首先登录到我们的服务器,在客户端服务器旁边,而不是路由器和交换机.这是脚本:文件名是connect.py:
import expect
class domain_connect:
def __init__(self,usr='user',pwd='password',d1='192.168.1.3',dclient='192.168.2.3'):
self._usr =us
self._pwd =pwd
self._d1 =d1
self._dclient =dclient
def djump(self):
child=pexpect.spawn('ssh -o StrictHostKeyChecking=no -l ' +self._usr+" "+self._d1)
child.expect('assword:')
child.sendline(self._pwd)
child.expect(':~>')
##Connect to client server
child.sendline(self._dclient)
child.expect('assword:')
child.sendline(self._pwd)
child.expect('accept:')
child.sendline(' ')
child.expect(':~>')
return child
class ce_connect:
def __init__(self, child, ip, usr, pwd, enpwd):
self._child = child
self._ip = ip
self._usr = usr
self._pwd = pwd
self._enpwd = pwd
def cjump(self):
##Connecting to router
child.sendline('ssh -o StrictHostKeyChecking=no -l '+self._usr+' '+self._ip)
return self._child
Run Code Online (Sandbox Code Playgroud)
这是使用的脚本:
import connect
child = connect.domain_connect()
child = child.djump() ## At this point I'm good toward the client server
Run Code Online (Sandbox Code Playgroud)
我试图执行以下操作将子对象传递给ce_connect类
child2 = connect.ce_connect(child, '192.78.1.20', 'username', 'password', 'password2')
child2 = child2.cjump()
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
AttributeError: 'spawn' object has no attribute 'djump'
Run Code Online (Sandbox Code Playgroud)
你已经被成功地传递child对象的ce_connect构造函数.
当你这样做:
child2 = connect.ce_connect(child, '192.78.1.20', 'username', 'password', 'password2')
Run Code Online (Sandbox Code Playgroud)
...传递child给ce_connect构造函数,因此child2._child最终成为同一个对象child.所以,当你打电话child2.cjump()和那个电话时self._child.dump(),它正在呼唤djump你的child对象.就像它应该的那样.
问题是它child不是一个domain_connect对象,它是一个pexpect.spawn对象.这就是你得到它的原因AttributeError: 'spawn' object has no attribute 'djump',这正是它所说的.
原因很简单:
child = child.djump()
Run Code Online (Sandbox Code Playgroud)
这设置child为任何djump回报.什么djump返回一个pexpect.spawn对象.在那之前,child是一个domain_connect,但现在,它是一个spawn,你不再有任何可访问的参考domain_connect.
答案很简单:不要这样做.保持domain_connect对它的引用,并使用它.像这样的东西:
child = connect.domain_connect()
child_jump = child.djump()
child2 = connect.ce_connect(child, '192.78.1.20', 'username', 'password', 'password2')
child2_jump = child2.cjump()
Run Code Online (Sandbox Code Playgroud)
作为旁注,我认为重用child方法实现中的名称和调用代码会使您感到困惑.如果你能提出不同的名字,那就更容易保持正确.
同时,一旦解决了这个问题,你就会遇到另一个问题.你的代码似乎期望childa ce_connect既是a domain_connect 又是a pexpect.spawn.特别是在里面ce_connect.cjump,你有这个:
child.sendline('ssh -o StrictHostKeyChecking=no -l '+self._usr+' '+self._ip)
Run Code Online (Sandbox Code Playgroud)
没有对象的sendline方法domain_connect.
这里很难确定正确的解决方案.你需要直截了当地了解这些对象应该是什么.他们为什么都叫child?什么是孩子应该是什么意思?
一种可能性是child对象应该是pexpect子进程,而不是*_connect对象,所以你真正想要的是这样的:
domain = connect.domain_connect()
child = domain.djump()
ce = connect.ce_connect(child, '192.78.1.20', 'username', 'password', 'password2')
child2 = ce.cjump()
Run Code Online (Sandbox Code Playgroud)
或者,也许你根本没有使用这些connect对象,只是它们djump/ cjump方法的结果.在这种情况下,您可以将其写为:
child = connect.domain_connect().djump()
child2 = connect.ce_connect(child, '192.78.1.20', 'username', 'password', 'password2').cjump()
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,你可能最好将公共接口作为一对模块级函数,并在这些函数的实现下隐藏类.
或者,也许你想让domain_connect对象作为子进程在它们所代表的任何其他东西之上,通过保持djump作为_child成员的结果,然后委托sendline,或者可能其他方法,到真实pexpect对象,如下所示:
def sendline(self, line):
return self._child.sendline(line)
Run Code Online (Sandbox Code Playgroud)
或者......好吧,正如我所说,有很多可能性,并且不知道你的设计应该如何工作以及你的类和变量应该代表什么,真的没有办法说明如何使你的代码适合你的设计.