أرسلت Kwargs عبر قناة PYAMF
سؤال
أنا أستخدم خادم 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، 2 = 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
المحلول
بشكل افتراضي، مجموعات Wsgigateway expose_request=True
مما يعني أن WSGI Environce Dict تم تعيين الوسيطة الأولى لأي طريقة خدمة في تلك العبارة.
هذا يعني أنه يجب كتابة الصدى على النحو التالي:
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
في هذه الحالة.
يمكنك الإشارة بشكل صحيح إلى أنه لا يمكنك توفير ** Kwargs مباشرة في مكالمة عميل / خادم PYAMF ولكن يمكنك استخدام المعلمات المسماة الافتراضية:
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)
نصائح أخرى
لاحظ أنه مع وظيفة الصدى الأولى الخاصة بك، فإن الطريقة الوحيدة للحصول على النتائج التي تقوم بها هي عندما تسمى بهذه الطريقة:
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
لهذا السبب، يجب عليك كتابة الصدى لقبول الحجج الموضعية أو تغيير كيفية استدعاءه.