代码之家  ›  专栏  ›  技术社区  ›  Luke404

在类似的多调用中包装xmlrpclib调用的pythonic方法

  •  0
  • Luke404  · 技术社区  · 14 年前

    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):
    

    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]
    

    但是它仍然为我需要实现的每个方法重复相同的三行代码,只是更改了被调用的方法名。好点了吗?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Eric Fortin    14 年前

    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部分需要与方法所需的内容保持一致,但是所有方法都使用一个参数。

    方法,然后调用返回的函数对象。注意处理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)