如何将函数中的变量传递给装饰器

时间:2018-04-02 01:41:08

标签: python decorator

我有一个函数,它定义了一个名为animal的变量。 我也有一个该函数的装饰器,但它需要在原始函数中定义的变量。

我需要原始函数中的动物变量,或者我需要以某种方式将装饰器中的model_data变量传递给原始函数。有什么输入吗?

以下是代码:

@csrf_exempt
@require_http_methods(["GET", "PUT", "DELETE"])
@parse_model_data
def base_animal(request, model_id):

    try:
        animal = Animal.objects.get(pk=model_id)
    except ObjectDoesNotExist:
        return json_error(error="No animal found for id: %s" % model_id)

    if request.method == "GET":
        return json_success(model=animal)

    if request.method == "DELETE":
        animal.delete()
        return json_success("Animal deleted.")

    if request.method == "PUT":
       animal.save()
       return json_success()

这是装饰器功能:

def parse_model_data(originalFunction):
  def parse(*args, **kwargs):
        request = args[0]
        model_data = request.get_json_body()
        if not model_data:
          return json_error("no json body detected")
        model_data = Animal.parse_model_data(model_data)
        for attr, value in model_data.items():
            setattr(animal, attr, value)
        return originalFunction(*args, **kwargs)

return parse

1 个答案:

答案 0 :(得分:3)

装饰师不是这个意思。它无法访问在函数内创建的对象,因为在调用修饰函数parse时该对象尚不存在。

看来你需要的是一个简单的函数。

def parse(animal, request):
    model_data = request.get_json_body()
    if not model_data:
      return json_error("no json body detected")
    model_data = Animal.parse_model_data(model_data)
    for attr, value in model_data.items():
        setattr(animal, attr, value)

@csrf_exempt
@require_http_methods(["GET", "PUT", "DELETE"])
def base_animal(request, model_id):
    try:
        animal = Animal.objects.get(pk=model_id)
    except ObjectDoesNotExist:
        return json_error(error="No animal found for id: %s" % model_id)

    # Here we use our parse function
    # It cannot be called before that point since animal did not exist
    parse(animal, request)

    ...