0

質問

2 つのクラスを同時に継承させる方法はありますか?

バックグラウンド

現在、Socket Server プロジェクトに取り組んでいます。このプロジェクトには、Serverクラスとクラスの 2 つのクラスがありGUIます。それらの目的は一目瞭然です。しかし、明らかに、2 つのクラスが相互に通信する必要があります。プログラムでは、最初にクラスを宣言し、Socket_Server次にクラスを宣言しGUIます。

同様の質問How to Access Functions from Methods in Pythonを尋ねましたが、満足のいく回答は得られませんでした。どちらかで答えてみてください。

コードとエラー

クラスには、すべてのクライアントにメッセージを送信するために使用さGUIれるというテキストボックスがあります。self.message.この構文を使用して、このクラスを継承しようとしました。

class Socket_Server(GUI.messageFun):

次に、GUI クラスは Socket_Server から継承します -

class GUI(Frame, Socket_Server): 

2 番目の継承GUI(Socket_Server)は正しく機能しますが、最初の継承は失敗します。

ボタンのコマンドはこれ

        self.send = Button (self.messageFrame, text = "Send",
                        command = lambda: new_server.send_cmd()) 

new_serverSocket_Serverクラスのインスタンスです。

現在のエラー メッセージは次のとおりです。

Socket Created
Socket Bind Complete
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "D:\Python Programs\Sockets\IM Project\Server\Server GUI InDev Class.py", line 129, in <lambda>
    command = lambda: new_server.send_cmd())
  File "D:\Python Programs\Sockets\IM Project\Server\Server GUI InDev Class.py", line 82, in send_cmd
    message = self.message.get("0.0",END)
AttributeError: Socket_Server instance has no attribute 'message'
4

2 に答える 2

2

この質問のタイトルは、最初に尋ねた質問とは異なります (そして少し正確です) が、どれもあなたが望むものに適合しません. 必要なのは、異なるクラスの 2 つのインスタンスを通信することです。それは継承ではありません。

継承を使用するときは、すべての X が Y でもあるかどうかを自問する必要があります。

  • すべてEmployeePerson? はい
  • すべてPersonEmployee? いいえ
  • すべてEmployeeCar? いいえ

この概念を念頭に置くと、3 番目の例が と の間の関係に最も似ていることがわかりGUIますServer。それは、あなたの本当の質問が次のとおりであるためです。

  • GUIインスタンスはServerオブジェクトを使用しますか?

答えが「はい」の場合、サーバーはGUIクラスの属性である必要があります。GUI次の例では、 がオブジェクトのメソッドを呼び出していることがわかりますがServer、その逆ではありません。

import Tkinter as tk
import threading
import socket

class Server():
    def __init__(self):
        self.addresses = [('localhost', 12345)] # All addresses to send data
    def sendtoall(self, data):
        for address in self.addresses:
            self._send(address, data)
    def _send(self, address, data):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(address)
            sock.sendall(data)
        finally:
            sock.close()

class GUI(tk.Tk):
    def __init__(self, server):
        tk.Tk.__init__(self)
        self.server = server
        self.entry = tk.Entry(self)
        self.button = tk.Button(self, text="Send", command= self.sendmessage)
        self.entry.pack()
        self.button.pack()
    def sendmessage(self):
        message = self.entry.get()
        threading.Thread(target=self.server.sendtoall, args=(message,)).start()

server = Server()
gui = GUI(server)
gui.mainloop()

編集:このコードはサーバーというよりもクライアントに似ているため、考えている概念に近い名前に変更することをお勧めします (例: Notifier)

于 2013-03-10T02:07:18.850 に答える
0

あなたが問題を抱えているのはオブジェクト指向です。継承がどのように機能するか、オブジェクトがどのように相互作用するかを調べる必要があります。そのため、1つの投稿でカバーするのは少し重い主題であり、経験を積んでその周りに頭を悩ませます。

tkinterに関する補足、コマンドプロパティはButtonが参照を取得します。これは、ボタンがクリックされるたびにその関数を呼び出すためです。

self.send = Button (self.messageFrame, text = "Send",
                        command = new_server.send_cmd())

つまり、コマンドはnew_server.send_cmd()の結果と同じです。

self.send = Button (self.messageFrame, text = "Send",
                    command = new_server.send_cmd)

これは、コマンドがsend_cmdメソッドへの参照に等しいことを示しています。

于 2013-03-10T01:10:03.943 に答える