【问题标题】:Flask - TypeError: Object of type cycle is not JSON serializableFlask - TypeError:类型循环的对象不是 JSON 可序列化的
【发布时间】:2020-09-26 19:26:11
【问题描述】:

客户端通过 AJAX 发帖后,我试图从服务器向客户端返回 json 响应。

像这样,它可以工作:

@app.route("/test", methods=["GET", "POST"])
@login_required
def test():

  if request.is_xhr:

    try:

      json_response = {
        "result": "success"
      }

    except Exception as e:
      err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
      json_response = {"result": "failure", "msg": err}

    return jsonify(json_response)

  else:
    return redirect("/not-found")

  return ''

如果我这样做,它不起作用:

@app.route("/test", methods=["GET", "POST"])
@login_required
def test():

  if request.is_xhr:

    try:

      _dict = {
        "key1": "value1",
        "key2": "value2"
      }

      if not "my_dict" in session:
        session["my_dict"] = [_dict]
      else:
        session["my_dict"] = session["my_dict"] + [_dict]

      session.modified = True

      json_response = {
        "result": "success"
      }

    except Exception as e:
      err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
      json_response = {"result": "failure", "msg": err}

    return jsonify(json_response)

  else:
    return redirect("/not-found")

  return ''

我收到以下错误并且客户端没有收到 json 响应:

File "~/myprojectenv/lib/python3.8/site-packages/flask/json/__init__.py", line 100, in default
    return _json.JSONEncoder.default(self, o)
  File "/usr/lib/python3.8/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type cycle is not JSON serializable
[2020-09-26 19:01:14,091] ERROR in app: Request finalizing failed with an error while handling an error

如果我删除那段:

      if not "my_dict" in session:
        session["my_dict"] = [_dict]
      else:
        session["my_dict"] = session["my_dict"] + [_dict]

      session.modified = True

它再次工作。客户端收到 json 响应。

【问题讨论】:

标签: python-3.x json flask


【解决方案1】:

我发现了问题。

查看以下函数:

@app.route("/test", methods=["GET", "POST"])
def test():
    if request.is_xhr:
        try:

            licycle = cycle(files)
            nextelem = next(licycle)

            _dict = {
                "sid": session["_id"],
                "licycle": licycle,
                "nextelem": nextelem,
                "licycle2": licycle2,
                "nextelem2": nextelem2,
                "mon_id": _id,
                "sch_id": 0
            }

            if not "all_submons" in session:
                session["all_submons"] = [_dict]
            else:
                session["all_submons"] = session["all_submons"] + [_dict]

            session.modified = True

            all_submons.setdefault("sub_mons", []).append(_dict)

            json_response = {"result": "success"}

        except Exception as e:
            err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
            json_response = {"result": "failure", "err": err}
        finally:
            try:
                print("exiting...")
            except Exception as e:
                pass

        return jsonify(json_response)

    else:
        return redirect("/not-found")

    return ""

原因是 licycle 变量的类型是 并且会话“可能不接受”这种类型的变量,如字典接受,正如您在我的 all_submons dict 变量中看到的那样。

重点是:

执行不会在异常中失败。 _dict 存储在会话中,你可以看到下一个。

print(f"Session before: {session}")
print(f"all_submons before: {all_submons}")

if not "all_submons" in session:
    session["all_submons"] = [_dict]
else:
    session["all_submons"] = session["all_submons"] + [_dict]

session.modified = True

all_submons.setdefault("sub_mons", []).append(_dict)

print(f"Session after: {session}")
print(f"all_submons after: {all_submons}\n")

你可以检查输出:

Session before: <SecureCookieSession {'_fresh': True, '_id': 'e253a950...', 'all_submons': [], 'user_id': '1'}>

all_submons before: {}

Session after: <SecureCookieSession {'_fresh': True, '_id': 'e253a...', 'all_submons': [{'sid': 'e253a95...', 'licycle': <itertools.cycle object at 0x7fc989237280>, 'nextelem': ('1a4add0f275c7275.jpg',), 'licycle2': None, 'nextelem2': None, 'mon_id': 1, 'sch_id': 0}], 'user_id': '1'}>

all_submons after: {'sub_mons': [{'sid': 'e253a...', 'licycle': <itertools.cycle object at 0x7fd6f1a17b80>, 'nextelem': ('1a4add0f275c7275.jpg',), 'licycle2': None, 'nextelem2': None, 'mon_id': 1, 'sch_id': 0}]}

我不确定会话“可能不接受”那种类型的变量 -

但是我用其他变量创建了其他字典,没有 itertools.cycle 的类型并且它有效。

【讨论】:

    猜你喜欢
    • 2019-07-12
    • 2017-11-09
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 2022-01-26
    • 2021-09-24
    • 2020-09-05
    相关资源
    最近更新 更多