[英]Two-Way communication between classes python (edited + code added)
因此,我有一些需要彼此通信的類。 例如,我建立了聊天程序的客戶端。 一類處理套接字,另一類處理GUI。 因此,GUI類必須從套接字類獲取接收到的數據,此外還必須通過套接字類發送消息。
問題是,如果使一個類包含另一個類,則無法雙向通信。 您需要將父實例傳遞給孩子,但我認為傳遞實例不是正確的方法。
最好的做法是什么?
這里以一些代碼為例,希望它清晰(請閱讀代碼中的注釋以更好地理解):
class MainWindow:
def __init__(self, master, username, sock):
# Tkinter Code Here
def insert_msg(self, data): # d_type 1 - msg
self.chat_textbox.insert(END, "\n%s %s" % (datetime.now().strftime('%H:%M:%S'), data))
self.chat_textbox.see(END)
def send_msg(self, data, d_type=SEND_ENUM.TYPE_MSG, arg=0):
data = str(data)
if len(data) >= 1 and d_type == SEND_ENUM.TYPE_MSG:
try:
self.chat_textbox.insert(END, "\n%s [Me] %s" % (datetime.now().strftime('%H:%M:%S'), data))
# For example, here has to use send_msg method from SockHandler class
# self.sock_handler.send_msg(data)
except sock_handling.ConnectionError as error:
self.chat_textbox.insert(END, "\nError: The message was not delivered", "RED")
else:
pass
finally:
self.msg_box_entry.delete(0, 'end')
self.chat_textbox.see(END)
elif d_type != SEND_ENUM.TYPE_MSG:
try:
# also here self.sock_handler.send_msg(data, d_type)
except sock_handling.ConnectionError as error:
pass
else:
pass
class SockHandler:
def __init__(self, client_socket):
# nothing relevant for the Q
def send_msg(self, data, d_type=SEND_ENUM.TYPE_MSG, arg=0):
packed_data = self.pack_data(d_type, arg, data)
if len(data) >= 1 and d_type == SEND_ENUM.TYPE_MSG:
try:
self.client_socket.send(packed_data)
except socket.error:
raise ConnectionError("Connection Error")
finally:
pass
elif d_type != SEND_ENUM.TYPE_MSG:
try:
self.client_socket.send(packed_data)
except socket.error:
raise ConnectionError("Connection Error")
def receive_data(self):
try:
while True:
recv_data = self.client_socket.recv(self.BUFFER)
(d_type,), data = struct.unpack("!I", recv_data[:4]), recv_data[4:]
if d_type == RECV_ENUM.TYPE_MSG:
# For example, here has to use insert_msg method from MainWindow class
elif d_type == RECV_ENUM.TYPE_USER_LIST:
pass
elif d_type == RECV_ENUM.TYPE_POKE:
pass
except socket.error:
self.client_socket.close()
raise ConnectionError("Connection Error")
為什么不將SockHandler
實例SockHandler
MainWindow
的屬性?
像這樣:
class MainWindow:
def __init__(self, master, username, sock):
# Tkinter Code Here
self.socket_handler = SockHandler(sock)
現在您可以使用self.socket_handler.send_msg
從MainWindow
發送消息
為了進行接收,請讓套接字存儲接收到的數據,以便MainWindow
可以在其中檢索數據。
像這樣:
class SockHandler:
def __init__(self, client_socket):
# nothing relevant for the Q
self.received_messages = Queue.Queue()
現在,您需要為MainWindow
提供一種訪問已接收消息的方法。 如果需要,您可以通過查詢隊列直接獲取消息,但我希望這樣:
# Within the SockHandler Class
def get_next_message():
try:
return self.received_messages.get(True, 5)
except:
return None
SockHandler
或MainWindow
在此方法中處理Timeout異常無關緊要。 那取決於你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.