通过 pyAMF 通道发送的 kwargs

发布于 2024-08-17 00:35:26 字数 1257 浏览 5 评论 0原文

我正在使用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

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

TypeError: 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

I'm using cherrypy server to receive requests over a pyAMF channel from a python client. I started with the mock up below and it works fine:

Server:

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())

Client:

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')

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

now if instead of:

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

I use:

def echo(**kwargs):
    return kwargs

and send the same request, I get the following error:

TypeError: echo() takes exactly 0 arguments (1 given)

while at the same time:

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

Question: Why is this happening? Please share insights

I'm using: python 2.5.2, cherrypy 3.1.2, pyamf 0.5.1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野生奥特曼 2024-08-24 00:35:26

请注意,对于第一个 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 来接受位置参数或更改它的调用方式。

Notice that with your first echo function, the only way to get the results you do is when it is called this way:

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

Because of this, you must write echo to accept positional arguments or change how it is called.

零度℉ 2024-08-24 00:35:26

默认情况下,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)

By default, WSGIGateway sets expose_request=True which means that the WSGI environ dict is set as the first argument to any service method in that gateway.

This means that echo should be written as:

def echo(environ, *args):
    return args

PyAMF provides a decorator which allows you to forcibly expose the request even if expose_request=False, an example:

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)

Hope that clarifies why you are getting the TypeError in this case.

You correctly point out that you cannot supply **kwargs directly in a PyAMF client/server call but you can use default named parameters:

def update(obj, force=False):
    pass

Then you can access the service:

from pyamf.remoting.client import RemotingService

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

print service.update('foo', True)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文