Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将输出序列化为JSON-ValueError:检测到循环引用_Python_Json_Python 2.7 - Fatal编程技术网

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

Python 将输出序列化为JSON-ValueError:检测到循环引用,python,json,python-2.7,Python,Json,Python 2.7,我正在尝试将mysql查询的结果输出到JSON。 我在序列化datetime.datetime字段时遇到问题,因此我编写了一个小函数来实现这一点: def date_handler(obj): if hasattr(obj, 'isoformat'): return obj.isoformat() else: return obj 然后在我刚刚运行的主代码中: products_json = [] for code in best_matchin

我正在尝试将mysql查询的结果输出到JSON。 我在序列化datetime.datetime字段时遇到问题,因此我编写了一个小函数来实现这一点:

def date_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.isoformat()
    else:
        return obj
然后在我刚刚运行的主代码中:

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_处理函数以来,我得到了“ValueError:检测到循环引用”


我打碎了什么?是否有更好的方法将输出序列化为JSON?

作为
默认值
参数传递的函数将仅用于
JSON
模块无法本机序列化的对象。它必须返回可序列化对象,或引发TypeError

如果所传递的对象不是您正在修复的类型(日期),则您的版本将返回相同的对象。这导致了循环引用错误(这是误导性的,因为循环经过
date\u handler
处理后位于一个对象和自身之间)

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

def date_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.isoformat()
    else:
        raise TypeError(
            "Unserializable object {} of type {}".format(obj, type(obj))
        )

您应该将调用转发到
jsonecoder
的默认方法,而不是自己引发
TypeError

def date_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.isoformat()
    else:
        json.JSONEncoder.default(self,obj)
这也会引起
TypeError
,这是一种更好的做法,它允许
jsonecoder
尝试编码您的方法无法编码的类型

json.dumps(obj, default=method_name)
“method_name”函数必须返回序列化对象


你能得到产品的打印输出吗?我猜在日期上有值的键之间有一些重复。然后它可以得到类似的错误。我得到了
namererror:global name'self'没有定义
只要尝试返回str(obj)就可以了。我在json中遇到了同样的数组列表问题,更改变量名后,得到的错误就消失了
json.dumps(obj, default=method_name)
def method_name(obj):
    data = {
            '__class__': obj.__class__.__name__,
            '__module__': obj.__module__
           }
    data.update(obj.__dict__)
    return data