首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >正在将输出序列化为JSON - ValueError:检测到循环引用

正在将输出序列化为JSON - ValueError:检测到循环引用
EN

Stack Overflow用户
提问于 2013-01-10 08:53:14
回答 3查看 54.2K关注 0票数 41

我正在尝试将mysql查询的结果输出到JSON。我在序列化datetime.datetime字段时遇到了问题,所以我写了一个小函数来做这件事:

代码语言:javascript
运行
复制
def date_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.isoformat()
    else:
        return obj

然后在主代码中,我只是运行:

代码语言:javascript
运行
复制
products_json = []
for code in best_matching_codes:
    cur = db.cursor()
    query = "SELECT * FROM %s WHERE code LIKE '%s'" % (PRODUCTS_TABLE_NAME, product_code)
    cur.execute(query)
    columns = [desc[0] for desc in cur.description]
    rows = cur.fetchall()
    for row in rows:
        products_json.append(dict((k,v) for k,v in zip(columns,row)))   

return json.dumps(products_json, default = date_handler)

然而,由于我编写了date_handler函数,我得到了"ValueError:检测到循环引用“

代码语言:javascript
运行
复制
127.0.0.1 - - [10/Jan/2013 00:42:18] "GET /1/product?code=9571%2F702 HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1701, in __call__
return self.wsgi_app(environ, start_response)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1689, in wsgi_app
response = self.make_response(self.handle_exception(e))
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1344, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/pisarzp/Desktop/SusyChoosy/susyAPI/test1.py", line 69, in product_search
return json.dumps(products_json, default = date_handler)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 201, in encode
chunks = self.iterencode(o, _one_shot=True)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 264, in iterencode
return _iterencode(o, 0)
ValueError: Circular reference detected

我弄坏了什么?有没有更好的方法将输出序列化为JSON?

EN

回答 3

Stack Overflow用户

发布于 2013-01-10 13:18:00

作为default参数传递的函数只会被json模块本身不能序列化的对象调用。它必须返回一个可序列化对象,或者引发一个TypeError。

如果该对象不是您正在修复的类型(Date),则您的版本将返回与传递给您的对象相同的对象。这会导致循环引用错误(这是误导性的,因为在date_handler处理之后,圆是在一个对象和它自己之间)。

您可以通过更改date_handler以在其else块中引发异常来开始修复此问题。这可能仍然会失败,但您可能会使用以下代码找出导致问题的数据结构中的对象:

代码语言:javascript
运行
复制
def date_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.isoformat()
    else:
        raise TypeError(
            "Unserializable object {} of type {}".format(obj, type(obj))
        )
票数 25
EN

Stack Overflow用户

发布于 2013-07-29 19:42:21

您应该将调用中继到JSONEncoder的默认方法,而不是自己引发默认方法:

代码语言:javascript
运行
复制
def date_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.isoformat()
    else:
        json.JSONEncoder.default(self,obj)

这也会引发TypeError,这是一个更好的做法,它允许JSONEncoder尝试并编码你的方法不能编码的类型。

票数 9
EN

Stack Overflow用户

发布于 2015-11-03 01:52:12

代码语言:javascript
运行
复制
json.dumps(obj, default=method_name)

"method_name“函数必须返回序列化对象。

代码语言:javascript
运行
复制
def method_name(obj):
    data = {
            '__class__': obj.__class__.__name__,
            '__module__': obj.__module__
           }
    data.update(obj.__dict__)
    return data
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14249115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档