如何包装xmlrpc函数调用? [英] How to wrap a xmlrpc function call?

查看:131
本文介绍了如何包装xmlrpc函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的xmlrpc服务器,定义为(server.py):

I have a simple xmlrpc server defined as (server.py):

from SimpleXMLRPCServer import SimpleXMLRPCServer

def foo():
    return "foo"

server = SimpleXMLRPCServer(("localhost", 1025))
server.register_introspection_functions()
server.register_function(foo, 'test.foo')
server.serve_forever()

和客户端(client.py)实现如下:

and the client (client.py) implemented as follows:

import xmlrpclib

class XMLRPC(object):

    def __init__(self):
        self.xmlrpc = xmlrpclib.ServerProxy("http://localhost:1025/RPC2")

    def __getattr__(self, name):
        attr = getattr(self.xmlrpc, name)
        def wrapper(*args, **kwargs):
            result = attr(*args, **kwargs)
            return result
        return wrapper

xmlrpc = XMLRPC()
print xmlrpc.test.foo()

我想包装并执行在XMLRPC类中对xmlrpc服务器进行的每个调用.但是上面的工作示例给出了错误

I want to wrap and execute each call that is being made to the xmlrpc server within the class XMLRPC. But the above working example gives an error

Traceback (most recent call last):
  File "client.py", line 20, in <module>
    xmlrpc.test.foo()
AttributeError: 'function' object has no attribute 'foo'

如何使此代码起作用?

How to make this code work?

其他信息和约束:

  • 我已经尝试用functools.wraps(attr)包装wrapper而不成功.由于字符串attr没有属性__name__,因此出现了另一个错误
  • 我无法更改server.py中定义的任何内容.
  • 上面的示例可以正常工作.
  • return attr代替return wrapper不是解决方案-我需要在wrapper中执行实际的xmlrpc调用.
  • 我需要一个没有第三方库的简单解决方案,标准的python库是可以的.
  • I already tried to wrap wrapper with functools.wraps(attr) without succcess. As the string attr has no attribute __name__ I get a different error
  • I canot change anything defined in server.py.
  • The above example is fully working.
  • Replacing return wrapper by return attr is not a solution - I need to execute the actual xmlrpc call within wrapper.
  • I need a simple solution without a 3rd party library, standard python libs are ok.

推荐答案

您需要返回一个可调用对象.

You need to return a callable object instead.

XML-RPC代理返回一个可调用对象的实例,但也可以遍历该对象.因此,对于xmlrpc.test.foo(),您将xmlrpc.test包装在函数中.该函数对象没有foo属性,因为函数通常没有这样的属性.

The XML-RPC proxy returns an instance of an object that is callable, but can also be traversed over. So for xmlrpc.test.foo(), you are wrapping xmlrpc.test in a function; that function object does not have a foo attribute because functions generally don't have such attributes.

返回一个代理对象; __call__挂钩使它成为可调用对象,就像一个函数一样:

Return a proxy object instead; the __call__ hook makes it a callable object, just like a function would be:

class WrapperProxy(object):
    def __init__(self, wrapped):
        self.wrapped = wrapped

    def __getattr__(self, name):
        attr = getattr(self.wrapped, name)
       return type(self)(attr)

    def __call__(self, *args, **kw):
        return self.wrapped(*args, **kw)

class XMLRPC(object):
    def __init__(self):
        self.xmlrpc = xmlrpclib.ServerProxy("http://localhost:1025/RPC2")

    def __getattr__(self, name):
        attr = getattr(self.xmlrpc, name)
        return WrapperProxy(attr)

或者,合并为一个对象:

or, merged into one object:

class XMLRPCWrapperProxy(object):
    def __init__(self, wrapped=None):
        if wrapped is None: 
            wrapped = xmlrpclib.ServerProxy("http://localhost:1025/RPC2")
        self.wrapped = wrapped

    def __getattr__(self, name):
        attr = getattr(self.wrapped, name)
       return type(self)(attr)

    def __call__(self, *args, **kw):
        return self.wrapped(*args, **kw)

这篇关于如何包装xmlrpc函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆