Can't figure out TypeError: __init__() takes exactly 3 arguments (2 given)

Can't figure out TypeError: __init__() takes exactly 3 arguments (2 given)

我正在开发一个多客户端/服务器聊天应用程序,它可以将一个客户端的输入写入多个客户端。对于客户端,它运行良好,但对于服务器端,我想添加一个部分,它也可以在自己的屏幕上打印出来自客户端的输入。当我处理它时,我遇到了 init() 的问题,正好有 3 个参数(给定的 2 个)与行 "self.app = app"

这是我的代码

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,它立即导致这种类型的错误。我该如何解决这个问题?

错误消息似乎很清楚:MultiClientEcho__init__ 方法需要三个参数(工厂和应用程序以及自动 self),但您只在实例化时传递 self 和 factory它在 buildProtocol 方法中。它应该从哪里得到 app

查看 __init__MultiClientEchoFactory 的定义:

def __init__(self, factory, app):

这需要三个参数才能运行(否则会抛出错误)。

你在这里调用这一行:

return MultiClientEcho(self)

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

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

    reactor.listenTCP(8000, MultiClientEchoFactory(self))

将工厂更改为:

def __init__(self, app):
    self.app = app
    self.clients = []

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

这将消除此错误,因为现在您将提供第三个 app 参数。

您在 class MultiClientEchoFactory 中调用 MultiClientEcho(self) 只有一个参数,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()