TypeError:<内置函数=“”id =“”>不是JSON可序列化</built-in>

时间:2014-07-04 21:54:58

标签: python json gerrit httplib

我试图建立与此网站的连接&#34; android-review.googlesource.com&#34;通过&#34; httplib.HTTPSConnection&#34;实际上是Gerrit(用于审查代码的工具),Gerrit API提供了JSON格式的审阅数据的接口。我需要收集JSON数据。您可以在此处找到有关Gerrit的更多信息:https://gerritreview.googlesource.com/Documentation/rest-api.html

让我解释一下源代码。有一个名为&#34; GetRequestOrCached&#34;它将数据保存在文件中以供缓存使用和另一个函数&#34; MakeRequest&#34;这将创建与网站的连接并返回响应。但是错误与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)

此行导致错误&#34; data = GetRequestOrCached(url,&#34; POST&#34;,json.dumps(req),filename)&#34;。 如果修复错误的人也检查网站的响应是错误还是正确的响应,我将不胜感激。

2 个答案:

答案 0 :(得分:6)

错误消息说明了所有内容 - req字典中包含id函数:

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

函数不是json可序列化的,所以这就是你得到错误的原因。

侧面说明 - 如果您想要传递变量,则在使用变量之前尚未对其进行初始化。避免将内置名称用作变量名称(例如idint,...)以避免此类问题。

答案 1 :(得分:1)

在分配给id时,您可能忘记分配给名为req的变量,然后再使用它。

因为你没有分配给它,所以名为id的内置函数被拾取并传递给json-ized。由于它是一个功能,它不能被json化。

如果同样的事情发生了一个并非碰巧是内置的名字,你就会得到:

UnboundLocalError: local variable referenced before assignment