Python使用self作为参数

时间:2011-12-20 16:46:25

标签: python class arguments self

我有两个类,一个处理GUI = GUI(),另一个处理与server = Client()的客户端连接。所以,我的错误报告将是:

TypeError: change_state() takes exactly 2 arguments (1 given)

在GUI()中的change_state()中使用self参数,并从Client()调用GUI.change_state('NORMAL')。

但是当在change_state()中没有自我作为参数时,我不能通过使用self来调用GUI类中的其他函数。并将GUI.change_state()更改为GUI().change_state 每次都会在GUI上调用__init__方法。 我希望你能理解我的意思 代码:

#!/usr/bin/python
import socket
import time
import tkinter
import threading
from tkinter import *

root = Tk()
root.geometry("363x200")
root.resizable(0,0)
root.title("Emsg")
b1 = None
b2 = None
class Client:
    def __init__(self, host='localhost', port=5000):
##        global b1
##        global b2
##        global b3
        try:
            self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server_socket.connect((host, port))
            time.sleep(0.5)
            GUI.set_info("Connected...")
            self.boool = True
            self.gotten = ""
            self.data = ""
            GUI.change_state('NORMAL') <<<<<<<<< Problem
            threading.Timer(1.0, self.listen).start()
        except socket.error as error:
            self.boool = False
            GUI.set_info(str(error)[14:])
##        except:
##            self.boool = False
##            GUI.set_info("An unknown error occured")


    def leave(self):
        self.boool = False
        self.server_socket.close()
        GUI.change_state('DISABLED')
        GUI.set_info("You have left the chat")
        GUI.set_v("", "")
        self.data = ""

    def listen(self):       
        while self.boool:
            try:
                time.sleep(0.1)
                self.data = self.server_socket.recv(512)
                if self.data == bytes('quit', 'UTF-8'):
                    self.leave()
                    GUI.set_info("Server has left the chat")
                    GUI.set_v("", "")
                elif self.data != self.gotten:
                    GUI.set_v("Server:", self.data, True)
                    self.gotten = self.data
            except socket.error:
                self.leave()


    def send(self, message=''):
        self.server_socket.send(bytes(message, 'UTF-8'))
        GUI.set_v("Client:", message)
        GUI.reset_cmsg()


class GUI:
    def __init__(self):
        self.client = None
        self.setup_buttons()

    def setup_buttons(self):
        global b1
        global b2
        global b3
        b1 = Button(root, text="Send", width=8, state=DISABLED, command=self.send)
        b1.grid(row=0, column=2)
        b2 = Button(root, text="Leave", width=8, state=DISABLED, command=self.leave)
        b2.grid(row=0, column=3)
        b3 = Button(root, text = "Connect", width = 8, command = self.connect)
        b3.grid(row = 0, column = 4)

    def connect(self):
        self.client = Client()
        self.first = True

    def leave(self):
        if self.client:
            self.client.leave()

    def send(self):
        if self.client:
            self.client.send(textEntry.get())

    def set_v(name, value, encoding=False):
        if encoding:
            v.set("%s: %s\n%s" % (name, str(value, 'UTF-8'), v.get()))
        else:
            v.set("%s: %s\n%s" % (name, value, v.get()))
        if name == "":
            v.set("")


    def change_state(self, _state):
        global b1
        global b2
        global b3
        if _state == 'DISABLED':
            b1.config(state=DISABLED)
            b2.config(state=DISABLED)
            b3.config(command=self.connect) <<<<<<<< Problem if changedto GUI().connect
            b3.config(text="Connect")
            textEntry.config(state=DISABLED)
        elif _state == 'NORMAL':
            b1.config(state=NORMAL)
            b2.config(state=NORMAL)
            b3.config(command=self.leave)
            b3.config(text="Disconnect")
            textEntry.config(state=NORMAL)

    def set_info(value):
        info.set(value)

    def reset_cmsg():
        c_msg.set("")












v = StringVar()
info = StringVar()
c_msg = StringVar()

Label(root, text="Enter: ").grid(row=0, column=0)
textEntry = Entry(root, state=DISABLED, textvariable=c_msg)
textEntry.grid(row=0, column=1)
statusField = Label(root, textvariable=info, wraplength=200)
statusField.grid(row=1, column=0, columnspan=5, sticky="w")
msgField = Message(root, textvariable=v, width=330, fg="blue")
msgField.grid(row=2, column=0, columnspan=5, sticky="w")

GUI()

root.mainloop()

2 个答案:

答案 0 :(得分:2)

您的问题相当模糊,但据我所知,您正在 GUI 类上调用change_state类方法。这不起作用,您应该实例化一个GUI对象,然后在其上调用change_state方法:

gui = GUI()
gui.change_state('NORMAL')

答案 1 :(得分:0)

你调用change_state函数,因为它是一个类方法

(见:http://docs.python.org/library/functions.html#classmethod

然而事实并非如此,你不能这样做,因为它引用了自我:

b3.config(command=self.connect) <<<<<<<< Problem if changedto GUI().connect

所以你应该在一个实例上调用change_state

gui = GUI()
gui.change_state('DISABLED')