我有一个类,我希望使用pythons SimpleXMLRPCServer作为远程服务公开.服务器启动如下所示:
server = SimpleXMLRPCServer((serverSettings.LISTEN_IP,serverSettings.LISTEN_PORT)) service = Service() server.register_instance(service) server.serve_forever()
然后我有一个ServiceRemote类,如下所示:
def __init__(self,ip,port): self.rpcClient = xmlrpclib.Server('http://%s:%d' %(ip,port)) def __getattr__(self, name): # forward all calls to the rpc client return getattr(self.rpcClient, name)
因此,ServiceRemote对象上的所有调用都将转发到xmlrpclib.Server,然后将其转发到远程服务器.问题是服务中采用名为varargs的方法:
@useDb def select(self, db, fields, **kwargs): pass
@useDb装饰器包装函数,在调用之前创建db并打开它,然后在调用完成之后关闭它,然后返回结果.
当我调用这个方法时,我得到错误" call()得到一个意外的关键字参数'name'".那么,是否可以远程调用采用变量命名参数的方法?或者我是否必须为我需要的每个方法变体创建一个覆盖.
谢谢你的回复.我改变了我的代码,所以问题不再是问题.但是现在我知道这个以供将来参考,如果我确实需要实现位置参数并支持远程调用.我认为Thomas和praptaks方法的结合会很好.通过xmlrpclient将kwargs转换为客户端上的位置args,并在方法服务器上使用包装器来解压缩位置参数.
你不能用普通的xmlrpc做到这一点,因为它没有关键字参数的概念.但是,您可以将此作为协议叠加在xmlrpc之上,该协议始终将列表作为第一个参数传递,将字典作为第二个参数传递,然后提供适当的支持代码,以使其对您的使用变得透明,如下所示:
from SimpleXMLRPCServer import SimpleXMLRPCServer class Server(object): def __init__(self, hostport): self.server = SimpleXMLRPCServer(hostport) def register_function(self, function, name=None): def _function(args, kwargs): return function(*args, **kwargs) _function.__name__ = function.__name__ self.server.register_function(_function, name) def serve_forever(self): self.server.serve_forever() #example usage server = Server(('localhost', 8000)) def test(arg1, arg2): print 'arg1: %s arg2: %s' % (arg1, arg2) return 0 server.register_function(test) server.serve_forever()
import xmlrpclib class ServerProxy(object): def __init__(self, url): self._xmlrpc_server_proxy = xmlrpclib.ServerProxy(url) def __getattr__(self, name): call_proxy = getattr(self._xmlrpc_server_proxy, name) def _call(*args, **kwargs): return call_proxy(args, kwargs) return _call #example usage server = ServerProxy('http://localhost:8000') server.test(1, 2) server.test(arg2=2, arg1=1) server.test(1, arg2=2) server.test(*[1,2]) server.test(**{'arg1':1, 'arg2':2})