TypeError: <内置函数 id> 不能序列化为 JSON

5 投票
2 回答
12044 浏览
提问于 2025-04-18 12:09

我正在尝试通过“httplib.HTTPSConnection”连接到这个网站“android-review.googlesource.com”,其实它是Gerrit(一个用于代码审查的工具)。Gerrit的API提供了一个接口,可以获取格式为JSON的审查数据。我需要收集这些JSON数据。你可以在这里找到关于Gerrit的更多信息:https://gerritreview.googlesource.com/Documentation/rest-api.html

让我简单解释一下源代码。有一个叫“GetRequestOrCached”的函数,它会把数据保存在文件中以便缓存使用,还有一个叫“MakeRequest”的函数,它会创建与网站的连接并返回响应。但是错误出现在使用json.dumps处理请求(req)的部分,而这个请求是一个字典。

这是错误信息:

TypeError: <built-in function id> is not JSON serializable

这是代码:

import socket, sys
import httplib
import pyodbc
import json
import types
import datetime
import urllib2
import os
import logging
import re, time

def GetRequestOrCached( url, method, data, filename):

  path = os.path.join("json", filename)
  if not os.path.exists(path):
    data = MakeRequest(url, method, data)
    time.sleep(1)
    data = data.replace(")]}'", "")
    f = open(path, "w")
    f.write(data)
    f.close()
    return open(path).read()

def MakeRequest(url, method, data, port=443):
  successful = False
  while not successful:
    try:
      conn = httplib.HTTPSConnection("android-review.googlesource.com", port)
      headers = {"Accept": "application/json,application/jsonrequest",
        "Content-Type": "application/json; charset=UTF-8",
        "Content-Length": len(data)}
      conn.request(method, url, data, headers)
      conn.set_debuglevel(1)
      successful = True
    except socket.error as err:
        # this means a socket timeout
      if err.errno != 10060:
        raise(err)
      else:
        print err.errno, str(err)
        print "sleep for 1 minute before retrying"
        time.sleep(60)

  resp = conn.getresponse()
  if resp.status != 200:
    raise GerritDataException("Got status code %d for request to %s" % (resp.status, url))
  return resp.read()
#-------------------------------------------------
filename = "%d-ChangeDetails.json"
url = "/gerrit_ui/rpc/ChangeDetailService"
req = {"jsonrpc" : "2.0", 
  "method": "changeDetail",
  "params": [{"id": id}],
  "id": 44
      }
data = GetRequestOrCached(url, "POST", json.dumps(req), filename)
print json.loads(data)

这一行导致了错误:“data = GetRequestOrCached(url, "POST", json.dumps(req), filename)”。如果能修复这个错误的人,也请检查一下从网站返回的响应是错误还是正确的。

2 个回答

2

你可能在给 req 赋值之前,忘记给名为 id 的变量赋值了。

因为你没有给它赋值,所以程序就用了一个内置的叫 id 的函数,并把它传了过去,想要把它转成 JSON 格式。可是因为它是个函数,所以不能被转成 JSON。

如果你用的名字恰好不是内置的名字,那你会看到:

UnboundLocalError: local variable referenced before assignment
6

错误信息已经说明了一切——你的 id 函数在你的 req 字典里面。

req = {"jsonrpc" : "2.0", 
  "method": "changeDetail",
  "params": [{"id": id}],
#                    ^- here
  "id": 44
}

函数是不能被转换成 JSON 格式的,这就是你看到这个错误的原因。

另外,如果你想传递一个变量的话,你在使用之前并没有先初始化它。尽量避免使用内置函数的名字作为变量名(比如 idint 等等),这样可以避免出现这种问题。

撰写回答