将 xmlrpclib 调用包装在类似的多重调用中的 pythonic 方法
我正在编写一个通过 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 方法,或者如果涉及身份验证,则将其包装在多重调用中授权。示例:
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]
但它仍然为我需要实现的每个方法重复相同的三行代码,只是更改调用的方法名称。有更好的吗?
I'm writing a class that interfaces to a MoinMoin wiki via xmlrpc (simplified code follows):
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):
now each of my methods needs to call the relevant xmlrpc method alone if there isn't authentication involved, or to wrap it in a multicall if there's auth. Example:
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
is there any nicer way to do it other than repeating that stuff for each and every method?
Since I have to call arbitrary methods, wrap them with stuff, then call the identically named method on another class, select relevant results and give them back, I suspect the solution would involve meta-classes or similar esoteric (for me) stuff. I should probably look at xmlrpclib sources and see how it's done, then maybe subclass their MultiCall to add my stuff...
But maybe I'm missing something easier. The best I've come out with is something like:
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]
but it still repeats the same three lines of code for each and every method I need to implement, just changing the called method name. Any better?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Python函数是对象,因此它们可以很容易地传递给其他函数。
可能还有其他方法,但我认为它应该有效。当然,arg 部分需要与方法所需的内容保持一致,但所有方法都采用一个参数。
编辑:我不明白 MultiCall 是代理对象。即使真正的方法调用最终是 ServerProxy 中的方法,您也不应该传递此方法对象,以防 MultiCall 覆盖(定义)它。在这种情况下,您可以使用 getattribute 方法以及要调用的方法名称,然后调用返回的函数对象。请注意处理 AttributeError 异常。
方法现在看起来像:
Python function are objects so they can be passed quite easily to other function.
There may be other way but I think it should work. Of course, the arg part needs to be aligned with what is needed for the method but all your methods take one argument.
Edit: I didn't understand that MultiCall was a proxy object. Even if the real method call ultimately is the one in your ServerProxy, you should not pass this method object in case MultiCall ever overrides(define) it. In this case, you could use the getattribute method with the method name you want to call and then call the returned function object. Take care to handle the AttributeError exception.
Methods would now look like: