[英]python twisted json decoding
I've got a following code developed using python twisted library: 我已经使用python扭曲库开发了以下代码:
class Cache(protocol.Protocol):
def __init__(self, factory):
self.factory = factory
def dataReceived(self, data):
request = json.loads(data)
self.factory.handle[request['command']](**request)
self.transport.write(data)
class CacheFactory(protocol.Factory):
def buildProtocol(self, addr):
return Cache(self)
def handle_get(self, **kwargs):
print 'get\n', kwargs
def handle_set(self, **kwargs):
print 'set\n', kwargs
def handle_delete(self, **kwargs):
print 'delete\n', kwargs
handle = {
'get': handle_get,
'set': handle_set,
'delete': handle_delete,
}
reactor.listenTCP(int(sys.argv[1]), CacheFactory())
reactor.run()
I run a client connection using telnet: 我使用telnet运行客户端连接:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
{"command": "set", "value": 1234567890}
Connection closed by foreign host.
an exception is thrown: 引发异常:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 84, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 69, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
return func(*args,**kw)
--- <exception caught here> ---
File "/usr/lib/python2.7/dist-packages/twisted/internet/selectreactor.py", line 146, in _doReadOrWrite
why = getattr(selectable, method)()
File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 460, in doRead
rval = self.protocol.dataReceived(data)
File "./server.py", line 18, in dataReceived
self.factory.handle[request['command']](**request)
exceptions.TypeError: handle_set() takes exactly 1 argument (0 given)
which I don't understand. 我不明白。 There could be something wrong with line
self.factory.handle[request['command']](**request)
, but in my opinion it's correct - it passes the self
parameter implicitly (it's a method afterall) and unpacked request parameter explicitly. self.factory.handle[request['command']](**request)
行可能有问题,但我认为这是正确的-它隐式地传递了self
参数(毕竟是方法)并显式地解压缩了请求参数。 The exception message says the function takes 1 argument, and it's a lie :) because it takes 2 parameters: self, **kwargs
. 异常消息说该函数接受1个参数,这是一个谎言:),因为它接受2个参数:
self, **kwargs
。 And it's not true that I pass 0 arguments, since I pass 2. 而且我传递了2个参数也不是正确的,因为我传递了2个参数。
Can someone help me to spot the problem? 有人可以帮助我发现问题吗?
in case it helps, the json request is decoded into: 如果有帮助,则将json请求解码为:
{u'command': u'set', u'value': 1234567890}
As it is now, the handle_*
methods are instance methods, yet the handle
dict points to unbound methods. 到目前为止,
handle_*
方法是实例方法,而handle
字典指向未绑定的方法。 That is, self
is not being passed implicitly. 也就是说,
self
不会被隐式传递。 Try this instead: 尝试以下方法:
class CacheFactory(protocol.Factory):
def buildProtocol(self, addr):
return Cache(self)
def handle_get(self, **kwargs):
print 'get\n', kwargs
def handle_set(self, **kwargs):
print 'set\n', kwargs
def handle_delete(self, **kwargs):
print 'delete\n', kwargs
def __init__(self, *args, **kwargs):
protocol.Factory.__init__(self, *args, **kwargs)
self.handle = {
'get': self.handle_get,
'set': self.handle_set,
'delete': self.handle_delete,
}
Alternatively, you could keep your handle
the same and do this: 另外,您可以保持
handle
不变并执行以下操作:
def dataReceived(self, data):
request = json.loads(data)
self.factory.handle[request['command']](self.factory, **request)
self.transport.write(data)
Or, you could take this approach and then you don't need a handle
dict either way: 或者,你可以采取这种做法,那么你并不需要一个
handle
字典两种方式:
def dataReceived(self, data):
request = json.loads(data)
getattr(self.factory, "handle_%s" % (request['command'],))(**request)
self.transport.write(data)
Also note your dataReceived
, as it is now, is unsafe, because packets might get split up arbitrarily - that is, you might not receive an entire json
message in one shot. 还要注意,由于数据包可能会被任意拆分,因此
dataReceived
(现在)是不安全的,也就是说,您可能不会一枪就收到整个json
消息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.