如何包装xmlrpc函数调用? [英] How to wrap a xmlrpc function call?
问题描述
我有一个简单的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
withfunctools.wraps(attr)
without succcess. As the stringattr
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
byreturn attr
is not a solution - I need to execute the actualxmlrpc
call withinwrapper
. - 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屋!