在python中运行时创建方法

时间:2016-12-08 22:48:22

标签: python rest decorator

我是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 - 名称为无的返回方法

我希望我能够清楚地解释我想要实现的目标。有没有办法解决它至少粗略地以我想要的方式解决它?

2 个答案:

答案 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

现在,当调用未在类中定义的方法时,会为其分配一个在处理函数中定义的修饰代码。