无法弄清楚TypeError:__ init __()需要3个参数(给定2个)

时间:2015-04-27 15:59:12

标签: python twisted kivy

我正在开发一个多客户端/服务器聊天应用程序,可以将输入从一个客户端写入多个客户端。对于客户端来说,它运行良好,但对于服务器端,我想添加一个部分,它可以在自己的屏幕上打印出来自客户端的输入。当我正在研究它时,我遇到了 init ()的问题,正好用“self.app = app”这一行获得了3个论点(给出了2个)

这是我的代码

import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.support import install_twisted_reactor
install_twisted_reactor()
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory

class MultiClientEcho(Protocol):

    def __init__(self, factory, app):
        self.factory = factory
        self.app = app

    def connectionMade(self):
        self.factory.clients.append(self)

    def dataReceived(self, data):
        for client in self.factory.clients:
             addtolog = self.factory.app.handle_message(data)
             if addtolog:
               client.transport.write(data)

    def connectionLost(self,reason):
        self.factory.clients.remove(self)

class MultiClientEchoFactory(Factory):
    protocol = MultiClientEcho
    def __init__(self):
        self.clients = []

    def buildProtocol(self, addr):
            return MultiClientEcho(self)


class ServerApp(App):
    def build(self):
        self.label = Label(text="server started\n")
        reactor.listenTCP(8000, MultiClientEchoFactory())
        return self.label

    def handle_message(self, msg):
        self.label.text = "received:  %s\n" % msg
        return msg


if __name__ == '__main__':
    ServerApp().run()

有趣的是,我只是改编自这个网站的源代码:http://kivy.org/docs/guide/other-frameworks.html,它本身也运行良好,但是一旦我将协议更改为MultiClientEcho,它立即导致了这种类型错误。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

查看__init__的{​​{1}}定义:

MultiClientEchoFactory

这需要三个参数才能运行(否则它会引发错误)。

你在这里称这一行:

def __init__(self, factory, app):

现在,return MultiClientEcho(self) 中的self将由__init__的此实例自动为您定义。 MultiClientEcho将被定义为factory的实例。但是,您还没有传递MultiClientEchoFactory的参数,因此python无法继续。

您可能要做的是将app函数中ServerApp的实例传递给build的构造函数:

MultiClientEchoFactory

将工厂更改为:

    reactor.listenTCP(8000, MultiClientEchoFactory(self))

将消除此错误,因为现在您将提供第三个def __init__(self, app): self.app = app self.clients = [] def buildProtocol(self, addr): return MultiClientEcho(self, self.app) 参数。

答案 1 :(得分:2)

您只使用一个参数MultiClientEcho(self)在课程MultiClientEchoFactory中呼叫factory

def buildProtocol(self, addr):
            return MultiClientEcho(self)

你应该尝试像

这样的东西
class MultiClientEchoFactory(Factory):
    protocol = MultiClientEcho
    def __init__(self,app):
        self.clients = []
        self.app=app

    def buildProtocol(self, addr):
            return MultiClientEcho(self,app)


class ServerApp(App):
    def build(self):
        self.label = Label(text="server started\n")
        reactor.listenTCP(8000, MultiClientEchoFactory(self))
        return self.label

    def handle_message(self, msg):
        self.label.text = "received:  %s\n" % msg
        return msg


if __name__ == '__main__':
    ServerApp().run()

答案 2 :(得分:0)

错误消息似乎很清楚:MultiClientEcho' __init__方法需要三个参数(工厂和应用以及自动自我),但您只能通过自我和工厂当您在buildProtocol方法中实例化它时。它应该从哪里获得app