我是python的新手,我正在尝试编写REST api调用的简单实现。我的目标是能够在运行时创建类的方法,并能够使用方法名作为API调用的基础。例如,list_virtual_networks将变为GET到http://localhost:8080/virtual-networks等。我还想练习一些更高级的面向对象技术。这是我的方法:
def _api_call_wrapper(wrapped_function):
def wrapper_function(*args, **kwargs):
handler_name = wrapped_function.__name__
agent_logger.info('Got function name {}'.format(handler_name))
<do something>
return res
return wrapper_function
class API(HTTPConnection):
def __init__(self, host, port):
<do something>
def __getattr__(self, name):
@_api_call_wrapper
def handler(self, *args, **kwargs):
self.request('GET', self.last_url)
return self.getresponse()
handler.__name__ = name
setattr(self, name, handler)
agent_logger.info('Returning method with name {}'.format(self.name))
if __name__ == '__main__':
api = API(127.0.0.1, 8080)
api.list_virtual_networks()
以下是我在日志中看到的内容:
2016-12-08 23:05:03,034 - AgentLogger - INFO - 名称函数wrapper_function的返回方法,位于0x1073c8d70&gt;
2016-12-08 23:05:03,034 - AgentLogger - INFO - 名称为无的返回方法
我希望我能够清楚地解释我想要实现的目标。有没有办法解决它至少粗略地以我想要的方式解决它?
答案 0 :(得分:0)
编写函数包装器时,一个很好的工具是Python的stdlib提供的wraps
库中的functools
函数:https://docs.python.org/3/library/functools.html#functools.wraps(特别是你想要的“重命名”东西)做)
from functools import wraps
def _api_call_wrapper(wrapped_function):
@wraps(wrapped_function)
def wrapper_function(*args, **kwargs):
handler_name = wrapped_function.__name__
agent_logger.info('Got function name {}'.format(handler_name))
<do something>
return res
return wrapper_function
答案 1 :(得分:0)
我找到了解决方案。我添加了一个装饰器,用于重命名函数
def _function_rename(new_name):
def decorator(f):
f.__name__ = new_name
return f
return decorator
然后我将这个装饰器应用于__getattr__中定义的处理函数,以及我已应用的装饰器:
def __getattr__(self, name):
@_api_call_wrapper
@_function_rename(name)
def handler(*args, **kwargs):
self.request(*args, **kwargs)
return self.getresponse()
return handler
现在,当调用未在类中定义的方法时,会为其分配一个在处理函数中定义的修饰代码。