如何在两个类之间共享数据

时间:2013-03-10 00:43:44

标签: python oop user-interface python-2.7 tkinter

问题

有没有办法让两个类同时继承?

背景

我目前正在开发一个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_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'

2 个答案:

答案 0 :(得分:2)

这个问题的标题与您在开头时提出的问题不同(并且更准确一些),但它们都不符合您的要求。你需要的是传达两个不同类的实例;这不是继承。

当你使用继承时,你应该问自己每个X是否也是Y:

  • 每个EmployeePerson吗?
  • 每个PersonEmployee吗? 没有
  • 每个EmployeeCar吗? 没有

考虑到这一概念,您可能会发现第三个示例与GUIServer之间的关系最相似。这是因为你真正的问题是:

  • 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方法的引用。