1

私はcherrypyサーバーを使用して、PythonクライアントからpyAMFチャネルを介してリクエストを受信して​​います。以下のモックアップから始めましたが、正常に機能します。

サーバ:

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

4

2 に答える 2

2

最初のエコー関数では、次のように呼び出されたときに結果を取得する唯一の方法であることに注意してください。

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

デフォルトでは、WSGIGatewayexpose_request=Trueが設定されます。これは、WSGIenvirondictがそのゲートウェイのサービスメソッドの最初の引数として設定されることを意味します。

これは、エコーを次のように記述する必要があることを意味します。

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 に答える