سؤال

أنا أستخدم خادم 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

لهذا السبب، يجب عليك كتابة الصدى لقبول الحجج الموضعية أو تغيير كيفية استدعاءه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top