我有一个提供与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)
这样做的好处是减少了样板的数量,并易于添加/删除路线。但是,在初始化时添加这些方法对我来说有点荒谬。
是否有更好和/或更惯用的方式来做到这一点?
答案 0 :(得分:2)
您可能会惊讶于这样做会达到目的:
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。