Витой питон: правильный способ пропустить kwarg через систему компонентов на завод
Мне нужно передать kwarg родительскому классу моего аналога FingerFactoryFromService, используя super.
Я знаю, что на самом деле передаю kwarg в IFingerFactory, потому что именно там я передаю сервис, который заканчивается в init FingerFactoryFromService, и я могу понять, что он срабатывает где-то в системе компонентов, но я не могу думать ни о каком другом пути.
Ошибка, которую я продолжаю получать,
exceptions.TypeError: 'test' is an invalid keyword argument for this function
Версии кода в моем virtualenv:
pip (1.4.1)
setuptools (1.1.6)
Twisted (13.1.0)
wsgiref (0.1.2)
zope.interface (4.0.5)
Это урезанный пример из учебника 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)
1 ответ
Решение
Это не имеет ничего общего с системой компонентов. То, что вы хотите сделать, это переопределить фабричный метод buildProtocol, как описано здесь:
https://twistedmatrix.com/documents/current/core/howto/servers.html