2

嗨,我想知道如何在班级之间传递对象。我将使用我的脚本首先登录到我们的服务器,在客户端服务器旁边,而不是路由器和交换机。这是脚本:文件名为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

这是使用的脚本:

import connect

child = connect.domain_connect()
child = child.djump() ## At this point I'm good toward the client server

我试图执行以下操作以将子对象传递给 ce_connect 类

    child2 = connect.ce_connect(child, '192.78.1.20', 'username', 'password', 'password2')
    child2 = child2.cjump()

我收到一个错误:

AttributeError: 'spawn' object has no attribute 'djump'
4

1 回答 1

5

您已经成功地将child对象传递给ce_connect构造函数。

当你这样做时:

child2 = connect.ce_connect(child, '192.78.1.20', 'username', 'password', 'password2')

... 传递childce_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()

这设置child为任何djump返回。djump返回的是一个对象pexpect.spawn。在该行之前,child是 a domain_connect,但现在,它是 a 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()

作为旁注,我认为child在方法实现和调用代码中重用名称会使您感到困惑。如果你能想出不同的名字,就更容易保持直截了当。


同时,一旦你解决了这个问题,你就会遇到另一个问题。您的代码似乎期望childace_connect同时是 adomain_connect a pexpect.spawn。特别是,在里面ce_connect.cjump,你有这个:

child.sendline('ssh -o StrictHostKeyChecking=no -l '+self._usr+' '+self._ip)

没有对象的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()

或者,也许您实际上根本没有使用这些connect对象,只是它们djump/cjump方法的结果。在这种情况下,您可以将其写为:

child = connect.domain_connect().djump()
child2 = connect.ce_connect(child, '192.78.1.20', 'username', 'password', 'password2').cjump()

但在这种情况下,您最好将公共接口设置为一对模块级函数,并将类隐藏在这些函数的实现下。

或者,也许您想让domain_connect对象在它们所代表的任何其他内容之上充当子进程,方法是保留djump作为_child成员的结果,然后将 以及可能的其他方法委托sendline给真实pexpect对象,如下所示:

def sendline(self, line):
    return self._child.sendline(line)

或者......好吧,正如我所说,有很多可能性,并且不知道你的设计应该如何工作以及你的类和变量应该代表什么,真的没有办法说如何让你的代码适合你的设计。

于 2013-03-29T22:48:13.173 回答