【问题标题】:Creating a Decorator创建装饰器
【发布时间】:2014-02-13 15:28:57
【问题描述】:

我正在从 HTTP GET 请求中获取一个值。我正在检查该值是否不等于无。如果是,则发送返回消息,否则正在进行进一步处理。

def api_servers():
    installation_name = request.args.get('installation_name', '')
    if installation_name == '':
        data = {"description": "Installation Name is required"}
        return HttpResponse(json.dumps(data), status=400, mimetype='application/json')

    data = { "arms": arms_list }

    return HttpResponse(json.dumps(data), status=200, mimetype='application/json')

现在,我想使用装饰器函数检查这个条件。这就是我正在尝试的。

def wrapper(func):
    def inner(): # I dont know what to pass in the arguments. Installation_name? 
                 # Maybe? But then how do I pass Installation_name

        if installation_name == '':
            data = {"description": "Installation Name is required"}
            return HttpResponse(json.dumps(data), status=400, mimetype='application/json')

        else: 
            return func()
    return inner 

如何通过装饰器实现这一点?

编辑 当我继续进行时,我发现我需要另一个装饰器来检查data 是否为None。它还检查installation_name 是否为空,然后我需要“回收”installation_name 和@ 987654328@。我又重写了你的代码。但值正在互换,即data 得到installation_name,反之亦然。你能看看吗?谢谢

def with_description(fn):

    def inner(*args, **kwargs):
    # Precheck
        installation_name = 'inst1'
        if installation_name == '':
            return 1

        # If precheck passes
        return fn(installation_name, *args, **kwargs)

    return inner


def with_description1(fn):

    def inner(*args, **kwargs):
    # Precheck
        data = 'data1'
        if data == '':
            return 1

        # If precheck passes
        return fn(data, *args, **kwargs)

    return inner

@with_description
@with_description1
def api_servers1(installation_name,data):
    print installation_name,data



api_servers1()

【问题讨论】:

  • func 会是什么?你能解释一下装饰器的流程吗?
  • @aIKid - func 将是api_servers。所以,流程是这样的。我得到了installation_name。我需要创建装饰器,它将检查installation_name 是否为'',然后返回调用包装函数的其他内容。

标签: python python-decorators


【解决方案1】:

嗯,试试看:

import functools

def with_description(fn):

    @functools.wraps(fn)  # This is not strictly necessary, just pulls info (docstrings, etc) from fn and pushes into the wrapper
    def wrapper(*args, **kwargs):
        # Precheck
        installation_name = request.args.get('installation_name', '')
        if installation_name == '':
            data = {"description": "Installation Name is required"}
            return HttpResponse(json.dumps(data), status=400, mimetype='application/json')

        # If precheck passes, call the actual function
        fn(*args, **kwargs)

    return wrapper

这样你就赢了,每个装饰的函数实际上只有在预检查通过时才会被调用。

编辑

如果您想回收安装名称,只需将其传递给函数调用即可。一种可能性如下:

fn(installation_name, *args, **kwargs)

当然,被装饰的函数必须期待那个参数。

【讨论】:

  • 效果很好。由于我在函数后面也需要installation_name,有什么方法可以从创建的装饰器中获取api_servers 函数中的installation_name 值?因为我不想在函数中再次获取installation_name 值,因此可以避免重复代码。
  • 在继续的过程中,我发现我需要另一个装饰器来检查data 是否为None。它还检查installation_name 是否为空,然后我需要“回收"installation_namedata。我又重写了你的代码。但是价值观正在互换。你能看看吗?我已经用我面临的问题编辑了我的问题。谢谢
  • 这是可行的,但你需要在两个不同的装饰器中使用它吗?
  • 是的。因为在某些功能中,我只需要使用一个装饰器进行测试,而在某些功能中需要使用另一个装饰器,而在某些功能中需要同时使用两个装饰器。
  • 好的,在这种情况下,我只需要在 kwargs 字典 (kwargs['installation_name'] = installation_name) 中包含您想要回收的变量,然后再添加 fn(*args, **kwargs)
猜你喜欢
  • 2017-11-16
  • 1970-01-01
  • 2017-02-04
  • 2011-12-25
  • 2015-03-28
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
  • 2020-05-12
相关资源
最近更新 更多