我有一个简单的 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'
如何使这段代码起作用?
附加信息和限制:
- 我已经尝试包装
wrapper
与functools.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/