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

すでにオブジェクトをコンストラクター正常に渡しています。childce_connect

これを行う場合:

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

…コンストラクタに渡さchildれるため、 と同じオブジェクトになります。したがって、あなたが を呼び出し、それが を呼び出すと、それはあなたのオブジェクトを呼び出しています。当然のことです。ce_connectchild2._childchildchild2.cjump()self._child.dump()djumpchild

問題は、それはオブジェクトでchildはなく、domain_connectオブジェクトだというpexpect.spawnことです。それがあなたがそれを得る理由ですAttributeError: 'spawn' object has no attribute 'djump'、それはまさにそれが言うことを意味します.

その理由は簡単です:

child = child.djump()

これは、返さ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()

補足として、childメソッドの実装内および呼び出しコード内で名前を再利用すると、混乱を招くと思います。明確な名前を思いつくことができれば、物事をまっすぐに保つのが簡単になります.


一方、これを修正すると、別の問題が発生します。あなたのコードはchild、 a のが aa のce_connect両方であると期待しているようです。特に、 の内部には、次のものがあります。domain_connect pexpect.spawnce_connect.cjump

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

オブジェクトのsendlineメソッドはありません。domain_connect

ここで正しい修正が何であるかを判断するのは困難です。これらの各オブジェクトがどうあるべきかを頭の中で真っ直ぐに理解する必要があります。なぜそれらはすべて呼ばれるのchildですか?子供とはどういう意味ですか?

1 つの可能性は、オブジェクトがオブジェクトではなく子プロセスで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_childsendlinepexpect

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

または…まあ、私が言ったように、多くの可能性があり、設計がどのように機能するか、クラスと変数が何を表すかを知らなければ、コードを設計に適合させる方法を言う方法はありません.

于 2013-03-29T22:48:13.173 に答える