我有一个类,提供API的简单接口。我想为每个路由在该类上定义一个方法。
由于大多数路由都是相同的,因此很多功能可以分解为更通用的功能,许多路由只是该功能的部分应用版本
class MyAPIWrapper:
def _get_results(self, route, **params):
# Do the important stuff here
results = ...
return results
def get_customers(self):
return self._get_results(self, 'customers')
def get_transactions(self):
return self._get_results(self, 'transactions')
# etc, etc, etc
但是,很明显,这仍然导致类定义中有相当数量的样板。
另一种方法是添加一种新方法,以编程方式添加每个路径的方法:
import functools
class MyAPIWrapper:
def __init__(self):
self._init_route_methods()
def _get_results(self, route, **params):
# Do the important stuff here
results = ...
return results
def _init_route_methods(self):
for route in ['customers', 'transactions', ...]:
route_fn = functools.partial(self. _get_results, route)
setattr(self, f'get_{route}', route_fn)
这样做的好处是可以减少样板量,并且可以轻松添加/删除路径。然而,在初始化时添加方法对我来说感觉有些不优雅。
是否有更好和/或更惯用的方法来做到这一点?
您可能会惊讶于这会解决问题:
class MyAPIWrapper:
def _get_results(self, route, **params):
# Do the important stuff here
return route
for route in ['customers', 'transactions']:
exec("""
def get_{0}(self):
return self._get_results('{0}')
""".strip().format(route))
MyAPIWrapper().get_customers() # return customers
MyAPIWrapper().get_transactions() # return transactions
请注意,exec
比setattr(MyAPIWrapper,'get_%s'%route, ...)
有一点开销,这只会影响你在循环中创建数百万种方法。
如果要对许多不同的APIWrapper类执行相同的操作,请考虑使用类decorator。