python - 如何包装 xmlrpc 函数调用?

标签 python wrapper xml-rpc xmlrpcclient

我有一个简单的 xmlrpc服务器定义为 ( 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)实现如下:

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 .但是上面的工作示例给出了一个错误

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

如何使这段代码起作用?

附加信息和限制:

  • 我已经尝试包装 wrapperfunctools.wraps(attr)没有成功。作为字符串 attr没有属性 __name__我得到一个不同的错误
  • 我无法更改 server.py 中定义的任何内容.
  • 上面的例子完全有效。
  • 替换 return wrapper通过 return attr不是解决方案 - 我需要执行实际的 xmlrpc内拨wrapper .
  • 我需要一个没有第 3 方库的简单解决方案,标准 python 库就可以了。

最佳答案

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

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

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

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)

或者,合并为一个对象:

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)

关于python - 如何包装 xmlrpc 函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17297169/

相关文章:

python - 使用 OpenCV 检测数字的小点或小数点

python - 为什么这个简单的骰子代码 'print' 没有任何内容?

c++ - 是否有用于 Windows 资源加载字符串的有用 C++ 包装器类?

python - wxPython 和 XMLRPC 线程化

java - 如何使用 XML-RPC 从单个类别中获取 WordPress 帖子

python - 如何使用 Python 创建 Word 文档?

c# - 为具有大量依赖项的库创建包装器的正确方法

c++ - 命名空间 C++ 库 (gloox) 的 objective-c 包装器

作为 Windows 服务的 Python XML-RPC 服务器

python - 构造函数中动态初始化数据库