问题
有没有办法让两个类同时继承?
背景
我目前正在开发一个Socket Server项目。在这个项目中,我有两个类,一个Server
类和一个GUI
类。他们的目的是自我解释。但是,我显然需要让两个班级相互沟通。在程序中,我首先声明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):
第二个继承GUI(Socket_Server)
正常工作,但第一个继承失败。
按钮的命令是这个
self.send = Button (self.messageFrame, text = "Send",
command = lambda: new_server.send_cmd())
new_server
是Socket_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'
答案 0 :(得分:2)
这个问题的标题与您在开头时提出的问题不同(并且更准确一些),但它们都不符合您的要求。你需要的是传达两个不同类的实例;这不是继承。
当你使用继承时,你应该问自己每个X是否也是Y:
Employee
是Person
吗? 是的Person
是Employee
吗? 没有 Employee
是Car
吗? 没有 考虑到这一概念,您可能会发现第三个示例与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()
编辑:此代码看起来更像是客户端而不是服务器,因此将其重命名为与您想到的概念更相似的内容可能是个好主意(例如,{{1 }})
答案 1 :(得分:0)
你遇到麻烦的是面向对象。你需要去了解继承是如何工作的,对象是如何相互作用的,所以要把它放在一个帖子中,这是一个很大的主题,并且需要经验来解决它。
关于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方法的引用。