本文最后更新于 2023年8月8日 早上
最近在整合各个语言模型,就涉及功能相同,但是命名千差万别的情况,于是用到了适配器模式,顺便产出本文简单说说该模式。
说明
适配器模式(Adapter Pattern)是一种结构型设计模式,它的主要目标是使得原本不兼容的接口能够相互工作。这种模式通常用于系统需要使用现有的类,而这些类的接口不符合系统的需求的情况。
在Python中,适配器模式可以用来解决两个接口不兼容的问题。例如,你可能有一个旧的代码库,或者一个来自第三方库的类,它的接口和你的代码不兼容。在这种情况下,你可以创建一个适配器,它包装了这个旧的类,并提供一个新的接口,使得旧的类可以被你的代码使用。
示例
假设chatgpt模型类如下,和模型相关的初始化由函数init实现,对话由函数request。就是随便写个例子,能够展示适配器效果就行了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class chatgpt:
def __init__(self) -> None:
self.name = "chatgpt"
print("chatgpt init")
def init(self):
print("chatgpt load")
def request(self) -> str:
return "chatgpt request"
|
然后另一个chatglm2的类,的模型相关初始化名字是awaken,对话函数是ack:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class chatglm2:
def __init__(self) -> None:
self.name = "chatglm2"
print("chatglm2 init")
def awaken(self):
print("chatglm2 load") def ack(self) -> str:
return "chatglm2 request"
|
假如已经写好了通用接口,定义模型初始化函数是load,对话函数是chat,上面的两个类中同样功能的函数名字各异,那么就使用适配器给搞成一样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| from typing import Callable, TypeVar T = TypeVar("T")
class Adapter: def __init__(self, obj: T, **adapted_methods: Callable): self.obj = obj self.__dict__.update(adapted_methods) print(self.__dict__)
def __getattr__(self, attr): return getattr(self.obj, attr)
def original_dict(self): return self.obj.__dict__ adaptee1 = chatgpt() adapter1 = Adapter(adaptee1, load=adaptee1.init, chat=adaptee1.request)
adapter1.load() print(adapter1.chat())
adaptee2 = chatglm2() adapter2 = Adapter(adaptee2, load=adaptee2.awaken, chat=adaptee2.ack)
adapter2.load() print(adapter2.chat())
|
这样就可以在后面使用的时候均统一函数名字,而不需要根据不同类去写判断。
上列代码输出:
1 2 3 4 5 6 7 8
| chatgpt init {'obj': <__main__.chatgpt object at 0x0000018DE98ABFD0>, 'load': <bound method chatgpt.init of <__main__.chatgpt object at 0x0000018DE98ABFD0>>, 'chat': <bound method chatgpt.request of <__main__.chatgpt object at 0x0000018DE98ABFD0>>} chatgpt load chatgpt request chatglm2 init {'obj': <__main__.chatglm2 object at 0x0000018DE98ABA30>, 'load': <bound method chatglm2.awaken of <__main__.chatglm2 object at 0x0000018DE98ABA30>>, 'chat': <bound method chatglm2.ack of <__main__.chatglm2 object at 0x0000018DE98ABA30>>} chatglm2 load chatglm2 request
|