Inside Flask - json 处理

博客围绕Flask中的JSON处理展开。JSON是处理web api时常用的数据交换格式,Flask对其做了包装,返回Response对象。介绍了Flask中JSON的实现、encoder和decoder的处理,还提及对unicode和html的处理,以及常用的jsonify函数使用注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Inside Flask - json 处理

在处理 web api 时,json 是非常好用的数据交换格式,它结构简单,基本上各种主流的编程语言都有良好的支持工具。

flask 中处理 json 时,对 json 加了一层包装,从而返回一个 Response 对象。简单的例子如下 ::

from flask import jsonify

...

@app.route('/hello')
def hello():
    result = {
        'status': 'success',
        'data': 'Hello, world!',
    }
    return jsonify(result)

flask 的 json 实现使用了 itsdangerous 中的 json 对象(来自 simplejson 或内置的 json),都在 flask/json.py 文件中。它在 json 的基础上加一些小的修改。对于 encoder ,增加了对 date ,UUID 和 内置 __html__ 属性(如 flask.Markup)等的处理 ::

class JSONEncoder(_json.JSONEncoder):
    ...
    def default(self, o):
        ...
        if isinstance(o, date):
            return http_date(o.timetuple())
        if isinstance(o, uuid.UUID):
            return str(o)
        if hasattr(o, '__html__'):
            return text_type(o.__html__())
        return _json.JSONEncoder.default(self, o) 

decoder 继承 _json.JSONDecoder ,没有修改。

除了基本的 dump / dumps / load / loads , flask 在这里还做了对 unicode 的处理和对 html 的转换处理。它提供了两个方法来处理 unicode 字符串 ::

def _wrap_reader_for_text(fp, encoding):
    if isinstance(fp.read(0), bytes):
        fp = io.TextIOWrapper(io.BufferedReader(fp), encoding)
    return fp
...
def _wrap_writer_for_text(fp, encoding):
    try:
        fp.write('')
    except TypeError:
        fp = io.TextIOWrapper(fp, encoding)
    return fp

对于在字节流, flask 在这里对它进行了包装,成为 unicode 文本流,再交给 json 处理。

对于 html ,由于html 中带有特殊的字符,需要转换 ::

def htmlsafe_dumps(obj, **kwargs):
    rv = dumps(obj, **kwargs) \
        .replace(u'<', u'\\u003c') \
        .replace(u'>', u'\\u003e') \
        .replace(u'&', u'\\u0026') \
        .replace(u"'", u'\\u0027')
    if not _slash_escape:
        rv = rv.replace('\\/', '/')
    return rv

最后,就是我们在处理 json 常用的 jsonify 函数 ::

def jsonify(*args, **kwargs):
    indent = None
    separators = (',', ':')

    if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] and not request.is_xhr:
        indent = 2
        separators = (', ', ': ')

    if args and kwargs:
        raise TypeError('jsonify() behavior undefined when passed both args and kwargs')
    elif len(args) == 1:  # single args are passed directly to dumps()
        data = args[0]
    else:
        data = args or kwargs

    return current_app.response_class(
        (dumps(data, indent=indent, separators=separators), '\n'),
        mimetype=current_app.config['JSONIFY_MIMETYPE']
    )

jsonify 函数在 dumps 的结果基础上,用 response_class 对结果进行了包装,并且给返回的数据头部的 mimetype 加上 json 类型(默认为 application/json ,可修改 JSONIFY_MIMETYPE 配置)

在使用 jsonify 函数时,需要注意只能使用 args 或 kwargs 其中一种方式,而 args 长度为1 时返回的是 args[0] 。其它模块也使用到 json 相关的功能,如 request 中从请求加载 json 数据等,用到 load 数据的功能。

转载于:https://www.cnblogs.com/fengyc/p/5870330.html

### 使用 Flask 开发桌面应用并结合 Tkinter 构建 GUI 程序 虽然 Flask 是一个专注于 Web 应用开发的框架,但它也可以被用来支持桌面应用程序的功能扩展。通过将 Flask 嵌入到桌面应用程序中,可以实现诸如数据同步、远程接口调用等功能。以下是关于如何使用 Flask 结合 Tkinter 来构建桌面 GUI 程序的具体方法。 #### 1. **Flask 提供的服务** Flask 可以为桌面应用提供后端服务支持,例如 RESTful API 接口或 WebSocket 实时通信。这些服务可以让桌面应用具备更强的数据处理能力或者联网功能[^1]。 #### 2. **集成 Flask 和 Tkinter** 将 Flask 集成到 Tkinter 中通常有两种常见方式:独立进程模式和嵌套调用模式。 ##### (1)**独立进程模式** 在这种模式下,Flask 运行在一个独立的线程或进程中,而 Tkinter 则运行在主线程中。这样可以避免阻塞 UI 主循环,并保持两者的解耦性。 ```python import threading from flask import Flask, jsonify import tkinter as tk from tkinter import Label, Button # 初始化 Flask 应用 app = Flask(__name__) @app.route('/api/data', methods=['GET']) def get_data(): return jsonify({'data': 'This is data from Flask!'}) def run_flask(): app.run(port=5000) # 启动 Flask 线程 flask_thread = threading.Thread(target=run_flask) flask_thread.daemon = True flask_thread.start() # 创建 Tkinter GUI root = tk.Tk() root.title("Flask + Tkinter Demo") label = Label(root, text="Welcome to the integrated Flask and Tkinter App!") label.pack(pady=20) def fetch_data_from_flask(): import requests response = requests.get('http://localhost:5000/api/data') result_label.config(text=response.json()['data']) fetch_button = Button(root, text="Fetch Data", command=fetch_data_from_flask) fetch_button.pack(pady=10) result_label = Label(root, text="") result_label.pack(pady=20) root.mainloop() ``` 在此示例中,当用户点击 “Fetch Data” 按钮时,Tkinter 会向 Flask 发起 GET 请求,并更新界面上的结果标签[^4]。 ##### (2)**嵌套调用模式** 如果希望更加紧密地结合 Flask 和 Tkinter,则可以选择让 Flask 完全依赖于 Tkinter 的控制流。这种方法适用于小型项目,其中 Flask 不需要长时间运行。 ```python from flask import Flask, jsonify import tkinter as tk from tkinter import Label, Button class FlaskApp: def __init__(self): self.app = Flask(__name__) @staticmethod @app.route('/api/data', methods=['GET']) def get_data(): return jsonify({'data': 'Data served by Flask inside Tkinter!'}) # 创建 Flask 应用实例 flask_app_instance = FlaskApp() # 创建 Tkinter GUI root = tk.Tk() root.title("Embedded Flask in Tkinter") label = Label(root, text="Integrated Flask within Tkinter") label.pack(pady=20) def show_flask_response(): label.config(text='Response: {}'.format(flask_app_instance.get_data())) button = Button(root, text="Show Response", command=lambda: show_flask_response()) button.pack(pady=10) root.mainloop() ``` 需要注意的是,在此情况下,由于 Flask 并未真正启动服务器监听外部连接,因此仅限于内部调用[^3]。 --- ### 总结 无论是采用独立进程还是嵌套调用的方式,都可以有效地将 Flask 和 Tkinter 整合成一个统一的应用程序体系结构。前者更适合大型复杂系统,后者则更适合作为快速原型验证的选择。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值