【问题标题】:Python Decorator Code Runs Before Original Function CodePython 装饰器代码在原始函数代码之前运行
【发布时间】:2014-01-31 15:21:37
【问题描述】:
def raw_list(function):
    @wraps(function)
    def wrapper(args, producer_data):
        print producer_data[2]
        tenant, token, url = producer_data
        body, status_code = do_request(url, token)
        return function(args, producer_data)
    return wrapper

@raw_list
def member_list(args, producer_data):
    # in argparse, consumer or producer data can be used because
    # consumer is aliased to producer.
    uuid = args['uuid']
    producer_data[2] = producer_data[2] + "/" + uuid + "/members"

我有几个函数可以获取 URL,对其进行变异,并使用 URL 进行 API 调用。出于这个原因,我为 API 调用部分制作了一个包装函数。因此,每个函数只需要修改 URL 并使用包装函数进行装饰。

但我遇到的问题是,变异的 URL 代码 producer_data[2] = producer_data[2] + "/" + uuid + "/members" 似乎在函数装饰器代码运行之后运行,而不是之前运行。因此,将使用原始 URL 而不是变异的 URL。

我怎样才能修复这个逻辑流并使它到达使用变异 URL 进行 API 调用的位置?

【问题讨论】:

  • 当然是事后运行,你事后在装饰器中调用!
  • 为什么要存储bodystatus_code,只是为了立即扔掉它们?它只是提醒do_request 返回的内容吗?
  • 部分功能可能会用到

标签: python python-2.7 decorator python-decorators


【解决方案1】:

如果您希望在包装器的其余代码之前调用修饰函数,请在包装器的其余代码之前调用它:

def raw_list(function):
    @wraps(function)
    def wrapper(args, producer_data):
        # Call it here!
        retval = function(args, producer_data)
        print producer_data[2]
        tenant, token, url = producer_data
        body, status_code = do_request(url, token)
        return retval
    return wrapper

【讨论】:

    【解决方案2】:

    改变 URL 的方法被称为装饰器的最后一条语句,这意味着您传递给 do_request 函数的 URL 是原始 URL。 您需要先调用修饰函数以获取 API URL,然后实际调用 do_request

    【讨论】:

      【解决方案3】:

      它将在装饰器代码之后运行,因为对函数的调用位于包装器的末尾。您提出请求并分配给bodystatus_code(尽管您从未对这些值做任何事情),然后调用member_list。它修改了producer_data,但到那时为时已晚。

      【讨论】:

        【解决方案4】:
        @xxx
        def yyy(): pass
        

        一样
        def yyy(): pass
        yyy = xxx(yyy)
        

        也许这会有所帮助。

        【讨论】:

          猜你喜欢
          • 2017-10-30
          • 2010-09-25
          • 2021-02-08
          • 2017-05-04
          • 1970-01-01
          • 2017-08-20
          • 2021-03-31
          • 1970-01-01
          相关资源
          最近更新 更多