Python装饰器代码在原始功能代码之前运行

时间:2014-01-31 15:21:38

标签: python python-2.7 decorator python-decorators

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调用的位置?

4 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

它将在装饰器代码之后运行,因为对函数的调用位于包装器的末尾。您发出请求并分配给bodystatus_code,(虽然您从未对这些值执行任何操作),然后致电member_list。它会修改producer_data,但到那时为时已晚。

答案 3 :(得分:0)

@xxx
def yyy(): pass

相同
def yyy(): pass
yyy = xxx(yyy)

也许这有帮助。