首先是代码:
class Api():
def __init__(self, baseurl='http://localhost:8080/api'):
self.base_url = baseurl
def _makerequest(self, arguments):
data = urllib.urlencode(arguments)
req = urllib2.Request(self.base_url, data)
response = urllib2.urlopen(req)
return response
def getId(self, **kwargs):
arguments = kwargs
arguments['Type'] = 'getId'
return self._makerequest(arguments)
def getKey(self, **kwargs):
arguments = kwargs
arguments['Type'] = 'getKey'
return self._makerequest(arguments)
正如您所看到的,每个函数最终都会调用_makerequest()
。我已经用这种方式编写了它,以便具有不同的功能(并且代码完成建议),但是最小化代码重用。
我想知道的是,如果一个人可能只有一个功能但是用不同的名称调用该功能。例如,我会调用getId()和getKey()但它会在类中触发相同的函数。
有关如何简化此操作的任何建议吗?
答案 0 :(得分:1)
如果你真的想要,你可以在没有这些包装函数的情况下使用makerequest
。如果你想要它更漂亮你可以做到:
def get(self, type, **kwargs):
arguments = kwargs
arguments['Type'] = 'Get'+type
return self.makerequest(arguments)
因此,您可以致电get('Id', args)
或get('Key', args)
。
答案 1 :(得分:1)
在我看来,你所例外的是你有样板代码
arguments = kwargs
arguments['Type'] = # Something
在每种API方法中。你能不能简单地做到以下几点:
def _makerequest(self, rtype, **kwargs):
kwargs['Type'] = rtype
data = urllib.urlencode(kwargs)
req = urllib2.Request(api.base_url, data)
response = urllib2.urlopen(req)
return response
允许你这样做:
def getId(self, **kwargs):
return self._makerequest('getId', **kwargs)
答案 2 :(得分:0)
这是Python作为动态语言真正得到回报的地方 - 很容易得到这样的工作。
class DynamicMethods(object):
def __init__(self):
pass
class HiddenImplementation(object):
''' we create a separate implementation class that:
1. stores the 'type' of the call (or whatever else you need to
store on a per-call basis)
2. define a __call__() method that lets us perform whatever our
dynamic method call needs to do. In this example, we just print
the kwargs we're passed along with the call 'type'.
'''
def __init__(self, typeName):
self.typeName = typeName
def __call__(self, **kwargs):
args = kwargs
args['type'] = self.typeName
for k, v in args.items():
print "{0}: {1}".format(k, v)
def __getattr__(self, name):
''' any time code looks up an attribute that the class doesn't have
explicitly, this will be called. If the attribute being looked up
starts with 'get', we create a HiddenImplementation object and
return that.
'''
if name.startswith('get'):
return self.HiddenImplementation(name)
if __name__ == "__main__":
d = DynamicMethods()
d.getId(a=1, b=2, c=3)
...打印
bgporter@varese ~/temp:python dynamicFn.py
a: 1
c: 3
b: 2
type: getId
答案 3 :(得分:0)
您可以使用装饰器。这是一个简化的例子
In [21]: def make_request(func):
def _get_request(*args):
print func(*args)
return _get_request
In [26]: class Api(object):
@make_request
def hello(self, s):
return 'Hello, '+s
@make_request
def goodbye(self, s):
return 'Goodbye, '+s
In [27]: api = Api()
In [28]: api.hello('world')
Hello, world
In [29]: api.goodbye('world')
Goodbye, world
答案 4 :(得分:0)
与任何其他对象相同,因此这个对象绑定的名称是完全免费的,甚至可能没有名称 - 想想返回值是函数,还是lambdas。给_makerequests
一个类型参数并将重复的代码移出get-methods。