我有一个无法修改的外部API。对于每次调用此API,我需要能够在之前和之后执行操作。此API使用如下:
def get_api():
"""
Return an initiated ClassAPI object
"""
token = Token.objects.last()
api = ClassAPI(
settings.CLASS_API_ID,
settings.CLASS_API_SECRET,
last_token)
return api
在代码中的任何地方都会调用 get_api()
,然后将结果用于执行请求(例如:api.book_store.get(id=book_id)
)。
我的目标是返回一个虚拟对象,它将执行与ClassAPI
添加打印相同的操作"之前"并打印"之后"。
ClassAPI
看起来像这样:
class ClassAPI
class BookStore
def get(...)
def list(...)
class PenStore
def get(...)
def list(...)
我尝试创建一个继承自(ClassApi, object)
[因为ClassAPI
并不继承自object
]的类,并在此类中添加一个装饰所有方法的元类,但是我无法影响BookStore
(获取和列表)
有关如何仅修改get_api()
并添加其他类的任何想法?我尽量避免复制API的整个结构来添加我的操作。
我正在使用python 2.7。
答案 0 :(得分:1)
您可以使用代理执行此操作:
class Proxy:
def __init__(self, other):
self.other = other
self.calls = []
def __getattr__(self, name):
self.calls.append(name)
return self
def __call__(self, *args, **kwargs):
self.before()
ret = self.call_proxied(*args, **kwargs)
self.after()
return ret
def call_proxied(self, *args, **kwargs):
other = self.other
calls = self.calls
self.calls = []
for item in calls:
other = getattr(other, item)
return other(*args, **kwargs)
此类拦截__getattr__()
方法中的未知成员,保存使用的名称并返回自身。
当一个方法被调用时(例如api.book_store.get(id=book_id)
),它会在自身上调用before()
和after()
方法,并在它之间获取other
和前进的成员通话中的参数。
您可以像这样使用此类:
def get_api():
...
return Proxy(api)
更新:更正了对self.call_proxied(*args, **kwargs)
的通话。还允许返回任何返回值。