-
Notifications
You must be signed in to change notification settings - Fork 22
/
json.py
103 lines (90 loc) · 3.13 KB
/
json.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""
JSON convenience routines.
"""
import simplejson
loads = simplejson.loads
_dumps = simplejson.dumps
load = simplejson.load
_dump = simplejson.dump
# From http://stackoverflow.com/a/2680060
import datetime
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.datetime) else None
dumps = lambda f: _dumps(f, default=dthandler)
dump = lambda f: _dump(f, default=dthandler)
from common.stats import stats
from common.file import myopen
from common.str import percent
import sys
def loadfile(filename, verbose=False):
"""
Load JSON from a filename.
"""
if verbose: print >> sys.stderr, "common.json.loadfile(%s)...\n%s" % (repr(filename), stats())
object = load(myopen(filename))
if verbose: print >> sys.stderr, "...common.json.loadfile(%s)\n%s" % (repr(filename), stats())
return object
def dumpfile(object, filename, verbose=False, **kwargs):
"""
Dump JSON to a filename.
"""
if verbose: print >> sys.stderr, "common.json.dumpfile(object, %s)...\n%s" % (repr(filename), stats())
r = _dump(object, myopen(filename, "wb"), **kwargs)
if verbose: print >> sys.stderr, "...common.json.dumpfile(object, %s)\n%s" % (repr(filename), stats())
return r
def loadoneperline(f, verbose=True):
"""
Read a JSON file object, one JSON object per line, and return a
dictionary containing everything.
Useful for JSON files that are big and crash simplejson when then
are loaded into memory.
"""
obj = {}
i = 0
if verbose:
print >> sys.stderr, "loadoneperline(%s)..." % f
print >> sys.stderr, stats()
for l in f:
i += 1
try:
o = loads(l)
assert len(o.keys()) == 1
key = o.keys()[0]
obj[key] = o[key]
except:
print >> sys.stderr, "Problem with:", l
if i % 1000000 == 0:
print >> sys.stderr, "\t...loadoneperline read %d lines..." % i
print >> sys.stderr, "\t%s" % stats()
if verbose:
print >> sys.stderr, "...loadoneperline(%s)" % f
print >> sys.stderr, stats()
return obj
def dumponeperline(obj, f, verbose=True):
"""
Write a JSON file object, one JSON object per line.
Useful for JSON objects that are big and use a lot of memory when
converted into strings.
"""
if verbose:
print >> sys.stderr, "dumponeperline(%s)..." % f
print >> sys.stderr, stats()
i = 0
for k in obj:
i += 1
o = {k: obj[k]}
# TODO: Make sure that dumps returns only one line?
f.write(dumps(o) + "\n")
if i % 1000000 == 0:
print >> sys.stderr, "\t...dumponeperline wrote %s lines..." % percent(i, len(obj))
print >> sys.stderr, "\t%s" % stats()
if verbose:
print >> sys.stderr, "...dumponeperline(%s)" % f
print >> sys.stderr, stats()
try:
import jsonlib
def fastloads(str): return jsonlib.read(str, use_float=True)
fastdumps = jsonlib.write
def fastloadfile(filename): return jsonlib.read(myopen(filename).read(), use_float=True)
def fastload(file): return jsonlib.read(file.read(), use_float=True)
except:
pass