Twisted python:将kwarg通过组件系统传递到工厂的正确方法

2024-09-30 16:23:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要使用super向FingerFactoryFromService的父类传递一个kwarg。在

我知道我实际上是在把kwarg传递给IFingerFactory,因为这也是我将服务传递到initFingerFactoryFromService的地方,我可以理解它在组件系统的某个地方被绊倒了,但我想不出其他方法。在

我一直得到的错误是

exceptions.TypeError: 'test' is an invalid keyword argument for this function

我的virtualenv中的代码版本是:

^{pr2}$

这是finger教程中的简化示例,演示了该问题:

from twisted.protocols import basic

from twisted.application import internet, service
from twisted.internet import protocol, reactor, defer
from twisted.python import components
from zope.interface import Interface, implements  # @UnresolvedImport


class IFingerService(Interface):

    def getUser(user):  # @NoSelf
        """
        Return a deferred returning a string.
        """

    def getUsers():  # @NoSelf
        """
        Return a deferred returning a list of strings.
        """


class IFingerFactory(Interface):

    def getUser(user):  # @NoSelf
        """
        Return a deferred returning a string.
        """

    def buildProtocol(addr):  # @NoSelf
        """
        Return a protocol returning a string.
        """


def catchError(err):
    return "Internal error in server"


class FingerProtocol(basic.LineReceiver):

    def lineReceived(self, user):
        d = self.factory.getUser(user)
        d.addErrback(catchError)

        def writeValue(value):
            self.transport.write(value + '\r\n')
            self.transport.loseConnection()
        d.addCallback(writeValue)


class FingerService(service.Service):

    implements(IFingerService)

    def __init__(self, filename):
        self.filename = filename
        self.users = {}

    def _read(self):
        self.users.clear()
        for line in file(self.filename):
            user, status = line.split(':', 1)
            user = user.strip()
            status = status.strip()
            self.users[user] = status
        self.call = reactor.callLater(30, self._read)  # @UndefinedVariable

    def getUser(self, user):
        print user
        return defer.succeed(self.users.get(user, "No such user"))

    def getUsers(self):
        return defer.succeed(self.users.keys())

    def startService(self):
        self._read()
        service.Service.startService(self)

    def stopService(self):
        service.Service.stopService(self)
        self.call.cancel()


class FingerFactoryFromService(protocol.ServerFactory):

    implements(IFingerFactory)

    protocol = FingerProtocol

    #def __init__(self, srv):
    def __init__(self, srv, test=None):
        self.service = srv
        ## I need to call super here because my equivalent of ServerFactory requires 
        ## a kwarg but this cutdown example doesnt so I just assign it to a property
        # super(FingerFactoryFromService, self).__init__(test=test)
        self.test_thing = test or 'Default Something'

    def getUser(self, user):
        return self.service.getUser(user)

components.registerAdapter(FingerFactoryFromService,
                           IFingerService,
                           IFingerFactory)

application = service.Application('finger')
serviceCollection = service.IServiceCollection(application)

finger_service = FingerService('/etc/passwd')
finger_service.setServiceParent(serviceCollection)

#line_finger_factory = IFingerFactory(finger_service)
line_finger_factory = IFingerFactory(finger_service, test='Something')
line_finger_server = internet.TCPServer(1079, line_finger_factory)
line_finger_server.setServiceParent(serviceCollection)  

Tags: fromtestimportselfdefservicelinetwisted