1

我正在使用cherrypy 服务器通过pyAMF 通道从python 客户端接收请求。我从下面的模型开始,它工作正常:

服务器:

import cherrypy
from pyamf.remoting.gateway.wsgi import WSGIGateway

def echo(*args, **kwargs):
    return (args, kwargs)

class Root(object):
    def index(self):
        return "running"
    index.exposed = True

services = {
   'myService.echo': echo,
}

gateway = WSGIGateway(services, debug=True)

cherrypy.tree.graft(gateway, "/gateway/")
cherrypy.quickstart(Root())

客户:

from pyamf.remoting.client import RemotingService

path = 'http://localhost:8080/gateway/'
gw = RemotingService(path)
service = gw.getService('myService')

print service.echo('one=1, two=3')

结果: [[u'one=1, two=3'], {}]

现在如果不是:

def echo(*args, **kwargs):
    return (args, kwargs)

我用:

def echo(**kwargs):
    return kwargs

并发送相同的请求,我收到以下错误:

类型错误:echo() 正好采用 0 个参数(给定 1 个)

同时:

>>> def f(**kwargs): return kwargs
... 
>>> f(one=1, two=3)
{'two': 3, 'one': 1}
>>> 

问:为什么会这样?请分享见解

我正在使用:python 2.5.2、cherrypy 3.1.2、pyamf 0.5.1

4

2 回答 2

2

请注意,使用您的第一个 echo 函数,获得结果的唯一方法就是以这种方式调用它:

echo(u"one=1, two=3")
# in words: one unicode string literal, as a positional arg

# *very* different from:
echo(one=1, two=3) # which seems to be what you expect

因此,您必须编写 echo 来接受位置参数或更改它的调用方式。

于 2010-01-07T22:45:17.587 回答
1

默认情况下,WSGIGateway 设置expose_request=True这意味着 WSGI 环境字典被设置为该网关中任何服务方法的第一个参数。

这意味着 echo 应该写成:

def echo(environ, *args):
    return args

PyAMF 提供了一个装饰器,它允许您强制公开请求,即使expose_request=False,例如:

from pyamf.remoting.gateway import expose_request
from pyamf.remoting.gateway.wsgi import WSGIGateway

@expose_request
def some_service_method(request, *args):
    return ['some', 'thing']

services = {
    'a_service_method': some_service_method
}

gw = WSGIGateway(services, expose_request=False)

希望这能澄清你TypeError在这种情况下得到的原因。

您正确地指出,您不能直接在 PyAMF 客户端/服务器调用中提供 **kwargs,但您可以使用默认命名参数:

def update(obj, force=False):
    pass

然后就可以访问服务了:

from pyamf.remoting.client import RemotingService

path = 'http://localhost:8080/gateway/'
gw = RemotingService(path)
service = gw.getService('myService')

print service.update('foo', True)
于 2010-01-08T02:16:57.003 回答