首页 > 解决方案 > 用于获取 JSON 请求的函数的 Python 装饰器

问题描述

我不能将url-details装饰函数传递给装饰器。

调试时,url-details装饰函数中的 将被忽略。如何使用装饰器解决该问题以避免重复代码?

编辑

有一个提供 JSON 数据的 Web 服务。我在代码库中发现了重复的代码:对于每个 get 请求,都有一个单独的函数(fetch_allfetch_keyfetch_date等)。每个函数都以相同的方式创建 URL ( url_base++ url_mid) url_details、定义标头和获取响应,只是 url_detail 不同。

现在我想以这种方式重构那些丑陋的重复代码:仅url_details在现有函数中定义并删除整个 url 创建、标头定义,最后将响应 (by requests.get(...)) 获取到装饰器中。

装饰者

def fetch(fnc):
    def wrapper(access_token, url_detail="", debug=None):
        headers = {"Authorization": "xxx " + access_token, "Accept": "application/json"}
        url = f"{url_base}{url_mid}{url_detail}"
        response = requests.get(url, headers=headers, verify=False)
        if debug:
            print(response)
        return response.content
    return wrapper

装饰功能

@fetch
def fetch_all(access_token):
    return access_token, ""

@fetch
def fetch_key(access_token, key=None):
    return access_token, f"/{key}"

@fetch
def fetch_date(access_token, date=""):
    return access_token, f"?date={date}", True

标签: pythonrequestdecorator

解决方案


我对你想要达到的目标有点困惑,但我知道你为什么会遇到困难。

通过装饰你的函数,@fetch你将原始函数传递为fnc.

然后,您将定义一个新函数 ( wrapper) 作为装饰器的结果返回。但是,您永远不会fnc从新函数中调用,这意味着它将永远不会运行!

wrapper无论您正在装饰的功能如何,您的装饰器都将始终返回相同的功能。

您当前的代码相当于

def wrapper(access_token, url_detail="", debug=None):
    headers = {"Authorization": "xxx " + access_token, "Accept": "application/json"}
    url = f"{url_base}{url_mid}{url_detail}"
    response = requests.get(url, headers=headers, verify=False)
    if debug:
        print(response)
    return response.content

fetch_all = wrapper
fetch_key = wrapper
fetch_date = wrapper

推荐阅读