我正在寻找一种方法来收集同类对象,将它们包装在另一个对象中,但包装器对象具有与原始对象相同的 API,并将相应的 API 调用转发给它的对象成员。
class OriginalApi:
def __init__(self):
self.a = 1
self.b = "bee"
def do_something(self, new_a, new_b, put_them_together=None):
self.a = new_a or self.a
self.b = new_b or self.b
if put_them_together is not None:
self.b = "{}{}".format(self.a, self.b)
# etc.
class WrappedApi:
def __init__(self):
self.example_1 = OriginalApi()
self.example_2 = OriginalApi()
已经考虑过但不充分的一些可能的解决方案:
重写整个 API 为什么不呢?不够,因为 API 相当大并且正在扩展。必须在多个位置维护 API 是不现实的。
代码示例:
class WrappedApi: def __init__(self): self.example_1 = OriginalApi() self.example_2 = OriginalApi() def do_something(self, new_a, new_b, put_them_together=None): self.example_1.do_something(new_a, new_b, put_them_together) self.example_2.do_something(new_a, new_b, put_them_together)
使用列表和 for 循环 这会更改对象的 API。也就是说,如果我找不到更优雅的东西,这是备用解决方案。在这种情况下,
WrappedApi
类将不存在。代码示例:
wrapped_apis = [OriginalApi(), OriginalApi()] for wrapped_api in wrapped_apis: wrapped_api.do_something(1, 2, True)
我尝试使用 Python Object Wrapper ,但我看不出如何让它使用相同的参数调用多个子对象。
对于任何对用例感兴趣的人来说,它实际上是几个 matplotlib axes
对象的集合。我不想重新实现整个 axes
API(它很大),我也不想更改所有调用轴的代码(比如 plot
, 步骤
等)
最佳答案
如果您只实现方法,那么通用 __getattr__
就可以做到这一点
class Wrapper:
def __init__(self, x):
self.x = x
def __getattr__(self, name):
def f(*args, **kwargs):
for y in self.x:
getattr(y, name)(*args, **kwargs)
return f
例如 x = Wrapper([[], [], []])
在调用 x.append(12)
之后,所有三个列表对象都将具有12 作为最后一个元素。
请注意,返回值将始终为 None
...一个选项可以收集返回值并将它们作为列表返回,但这当然会“破坏 API”。
关于python - 包装同类 Python 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55211193/