Я пишу класс, который взаимодействует с вики MoinMoin через xmlrpc (упрощенный код приведен ниже):
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]
но он все еще повторяет те же три строки кода для каждого метода, который мне нужно реализовать, просто меняя имя вызываемого метода. Лучше?