我正在编写一个通过xmlrpc连接到MoinMoin wiki的类(简化代码如下):
class MoinMoin(object):
token = None
def __init__(self, url, username=None, password=None):
self.wiki = xmlrpclib.ServerProxy(url + '/?action=xmlrpc2')
if username and password:
self.token = self.wiki.getAuthToken(username, password)
# some sample methods:
def searchPages(self, regexp):
def getPage(self, page):
def putPage(self, page):
现在,如果没有涉及身份验证,我的每个方法都需要单独调用相关的xmlrpc方法,或者如果有auth则将其包装在multicall中。例如:
def getPage(self, page):
if not self.token:
result = self.wiki.getPage(page)
else:
mc = xmlrpclib.MultiCall(self.wiki) # build an XML-RPC multicall
mc.applyAuthToken(self.token) # call 1
mc.getPage(page) # call 2
result = mc()[-1] # run both, keep result of the latter
return result
除了为每种方法重复这些东西之外,有没有更好的方法呢?
因为我必须调用任意方法,用东西包装它们,然后在另一个类上调用同名方法,选择相关结果并将它们还给我,我怀疑解决方案会涉及元类或类似的深奥(对我来说)东西。我应该看看xmlrpclib源代码,看看它是如何完成的,然后可能将它们的MultiCall子类化为我的东西...
但也许我错过了一些更容易的东西。我提出的最好的是:
def _getMultiCall(self):
mc = xmlrpclib.MultiCall(self.wiki)
if self.token:
mc.applyAuthToken(self.token)
return mc
def fooMethod(self, x):
mc = self._getMultiCall()
mc.fooMethod(x)
return mc()[-1]
但它仍然为我需要实现的每个方法重复相同的三行代码,只需更改被调用的方法名称。还好吗?
答案 0 :(得分:1)
Python函数是对象,因此可以很容易地将它们传递给其他函数。
def HandleAuthAndReturnResult(self, method, arg):
mc = xmlrpclib.MultiCall(self.wiki)
if self.token:
mc.applyAuthToken(self.token)
method(mc, arg)
return mc()[-1]
def fooMethod(self, x):
HandleAuthAndReturnResult(xmlrpclib.MultiCall.fooMethod, x)
可能有其他方式,但我认为它应该有效。当然,arg部分需要与方法所需的一致,但所有方法都需要一个参数。
编辑:我不明白MultiCall是一个代理对象。即使真正的方法调用最终是您的ServerProxy中的那个,也不应该传递此方法对象,以防MultiCall覆盖(定义)它。在这种情况下,您可以使用 getattribute 方法和要调用的方法名称,然后调用返回的函数对象。注意处理AttributeError异常。
现在的方法如下:
def HandleAuthAndReturnResult(self, methodName, arg):
mc = xmlrpclib.MultiCall(self.wiki)
if self.token:
mc.applyAuthToken(self.token)
try:
methodToCall = getattr(mc, methodName)
except AttributeError:
return None
methodToCall(arg)
return mc()[-1]
def fooMethod(self, x):
HandleAuthAndReturnResult('fooMethod', x)