python_json

来源:互联网 发布:mac中如何添加qq邮箱 编辑:程序博客网 时间:2024/05/25 18:11
10.4.1  使用 json.dump() 和 json.load()我们来编写一个存储一组数字的简短程序,再编写一个将这些数字读取到内存中的程序。第一个程序将使用 json.dump() 来存储这组数字,而第二个程序将使用 json.load() 。函数 json.dump() 接受两个实参:要存储的数据以及可用于存储数据的文件对象。下面演示了如何使用 json.dump() 来存储数字列表:number_writer.pyimport jsonnumbers = [2, 3, 5, 7, 11, 13]❶❷❸filename = 'numbers.json'with open(filename, 'w') as f_obj:json.dump(numbers, f_obj)

Json

import stringimport types##    json.py implements a JSON (http://json.org) reader and writer.##    Copyright (C) 2005  Patrick D. Logan##    Contact mailto:patrickdlogan@stardecisions.com####    This library is free software; you can redistribute it and/or##    modify it under the terms of the GNU Lesser General Public##    License as published by the Free Software Foundation; either##    version 2.1 of the License, or (at your option) any later version.####    This library is distributed in the hope that it will be useful,##    but WITHOUT ANY WARRANTY; without even the implied warranty of##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU##    Lesser General Public License for more details.####    You should have received a copy of the GNU Lesser General Public##    License along with this library; if not, write to the Free Software##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USAclass _StringGenerator(object):    def __init__(self, string):        self.string = string        self.index = -1    def peek(self):        i = self.index + 1        if i < len(self.string):            return self.string[i]        else:            return None    def next(self):        self.index += 1        if self.index < len(self.string):            return self.string[self.index]        else:            raise StopIteration    def all(self):        return self.stringclass WriteException(Exception):    passclass ReadException(Exception):    passclass JsonReader(object):    hex_digits = {'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F':15}    escapes = {'t':'\t','n':'\n','f':'\f','r':'\r','b':'\b'}    def read(self, s):        self._generator = _StringGenerator(s)        result = self._read()        return result    def _read(self):        self._eatWhitespace()        peek = self._peek()        if peek is None:            raise ReadException, "Nothing to read: '%s'" % self._generator.all()        if peek == '{':            return self._readObject()        elif peek == '[':            return self._readArray()                    elif peek == '"':            return self._readString()        elif peek == '-' or peek.isdigit():            return self._readNumber()        elif peek == 't':            return self._readTrue()        elif peek == 'f':            return self._readFalse()        elif peek == 'n':            return self._readNull()        elif peek == '/':            self._readComment()            return self._read()        else:            raise ReadException, "Input is not valid JSON: '%s'" % self._generator.all()    def _readTrue(self):        self._assertNext('t', "true")        self._assertNext('r', "true")        self._assertNext('u', "true")        self._assertNext('e', "true")        return True    def _readFalse(self):        self._assertNext('f', "false")        self._assertNext('a', "false")        self._assertNext('l', "false")        self._assertNext('s', "false")        self._assertNext('e', "false")        return False    def _readNull(self):        self._assertNext('n', "null")        self._assertNext('u', "null")        self._assertNext('l', "null")        self._assertNext('l', "null")        return None    def _assertNext(self, ch, target):        if self._next() != ch:            raise ReadException, "Trying to read %s: '%s'" % (target, self._generator.all())    def _readNumber(self):        isfloat = False        result = self._next()        peek = self._peek()        while peek is not None and (peek.isdigit() or peek == "."):            isfloat = isfloat or peek == "."            result = result + self._next()            peek = self._peek()        try:            if isfloat:                return float(result)            else:                return int(result)        except ValueError:            raise ReadException, "Not a valid JSON number: '%s'" % result    def _readString(self):        result = ""        assert self._next() == '"'        try:            while self._peek() != '"':                ch = self._next()                if ch == "\\":                    ch = self._next()                    if ch in 'brnft':                        ch = self.escapes[ch]                    elif ch == "u":                ch4096 = self._next()            ch256  = self._next()            ch16   = self._next()            ch1    = self._next()            n = 4096 * self._hexDigitToInt(ch4096)            n += 256 * self._hexDigitToInt(ch256)            n += 16  * self._hexDigitToInt(ch16)            n += self._hexDigitToInt(ch1)            ch = unichr(n)                    elif ch not in '"/\\':                        raise ReadException, "Not a valid escaped JSON character: '%s' in %s" % (ch, self._generator.all())                result = result + ch        except StopIteration:            raise ReadException, "Not a valid JSON string: '%s'" % self._generator.all()        assert self._next() == '"'        return result    def _hexDigitToInt(self, ch):        try:            result = self.hex_digits[ch.upper()]        except KeyError:            try:                result = int(ch)        except ValueError:             raise ReadException, "The character %s is not a hex digit." % ch        return result    def _readComment(self):        assert self._next() == "/"        second = self._next()        if second == "/":            self._readDoubleSolidusComment()        elif second == '*':            self._readCStyleComment()        else:            raise ReadException, "Not a valid JSON comment: %s" % self._generator.all()    def _readCStyleComment(self):        try:            done = False            while not done:                ch = self._next()                done = (ch == "*" and self._peek() == "/")                if not done and ch == "/" and self._peek() == "*":                    raise ReadException, "Not a valid JSON comment: %s, '/*' cannot be embedded in the comment." % self._generator.all()            self._next()        except StopIteration:            raise ReadException, "Not a valid JSON comment: %s, expected */" % self._generator.all()    def _readDoubleSolidusComment(self):        try:            ch = self._next()            while ch != "\r" and ch != "\n":                ch = self._next()        except StopIteration:            pass    def _readArray(self):        result = []        assert self._next() == '['        done = self._peek() == ']'        while not done:            item = self._read()            result.append(item)            self._eatWhitespace()            done = self._peek() == ']'            if not done:                ch = self._next()                if ch != ",":                    raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch)        assert ']' == self._next()        return result    def _readObject(self):        result = {}        assert self._next() == '{'        done = self._peek() == '}'        while not done:            key = self._read()            if type(key) is not types.StringType:                raise ReadException, "Not a valid JSON object key (should be a string): %s" % key            self._eatWhitespace()            ch = self._next()            if ch != ":":                raise ReadException, "Not a valid JSON object: '%s' due to: '%s'" % (self._generator.all(), ch)            self._eatWhitespace()            val = self._read()            result[key] = val            self._eatWhitespace()            done = self._peek() == '}'            if not done:                ch = self._next()                if ch != ",":                    raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch)    assert self._next() == "}"        return result    def _eatWhitespace(self):        p = self._peek()        while p is not None and p in string.whitespace or p == '/':            if p == '/':                self._readComment()            else:                self._next()            p = self._peek()    def _peek(self):        return self._generator.peek()    def _next(self):        return self._generator.next()class JsonWriter(object):    def _append(self, s):        self._results.append(s)    def write(self, obj, escaped_forward_slash=False):        self._escaped_forward_slash = escaped_forward_slash        self._results = []        self._write(obj)        return "".join(self._results)    def _write(self, obj):        ty = type(obj)        if ty is types.DictType:            n = len(obj)            self._append("{")            for k, v in obj.items():                self._write(k)                self._append(":")                self._write(v)                n = n - 1                if n > 0:                    self._append(",")            self._append("}")        elif ty is types.ListType or ty is types.TupleType:            n = len(obj)            self._append("[")            for item in obj:                self._write(item)                n = n - 1                if n > 0:                    self._append(",")            self._append("]")        elif ty is types.StringType or ty is types.UnicodeType:            self._append('"')        obj = obj.replace('\\', r'\\')            if self._escaped_forward_slash:                obj = obj.replace('/', r'\/')        obj = obj.replace('"', r'\"')        obj = obj.replace('\b', r'\b')        obj = obj.replace('\f', r'\f')        obj = obj.replace('\n', r'\n')        obj = obj.replace('\r', r'\r')        obj = obj.replace('\t', r'\t')            self._append(obj)            self._append('"')        elif ty is types.IntType or ty is types.LongType:            self._append(str(obj))        elif ty is types.FloatType:            self._append("%f" % obj)        elif obj is True:            self._append("true")        elif obj is False:            self._append("false")        elif obj is None:            self._append("null")        else:            raise WriteException, "Cannot write in JSON: %s" % repr(obj)def write(obj, escaped_forward_slash=False):    return JsonWriter().write(obj, escaped_forward_slash)def read(s):    return JsonReader().read(s)

minijson

##################################################################################    minjson.py implements JSON reading and writing in python.##    Copyright (c) 2005 Jim Washington and Contributors.####    This library is free software; you can redistribute it and/or##    modify it under the terms of the GNU Lesser General Public##    License as published by the Free Software Foundation; either##    version 2.1 of the License, or (at your option) any later version.####    This library is distributed in the hope that it will be useful,##    but WITHOUT ANY WARRANTY; without even the implied warranty of##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU##    Lesser General Public License for more details.=####    You should have received a copy of the GNU Lesser General Public##    License along with this library; if not, write to the Free Software##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA################################################################################# minjson.py# use python's parser to read minimal javascript objects.# str's objects and fixes the text to write javascript.# Thanks to Patrick Logan for starting the json-py project and making so many# good test cases.# Jim Washington 7 Aug 2005.from re import compile, sub, search, DOTALL# set to true if transmission size is much more important than speed# only affects writing, and makes a minimal difference in output size.alwaysStripWhiteSpace = False# add to this string if you wish to exclude additional math operators# from reading.badOperators = '*'##################################      read JSON object         ##################################slashstarcomment = compile(r'/\*.*?\*/',DOTALL)doubleslashcomment = compile(r'//.*\n')def _Read(aString):        """Use eval in a 'safe' way to turn javascript expression into           a python expression.  Allow only True, False, and None in global           __builtins__, and since those map as true, false, null in           javascript, pass those as locals        """        try:            result = eval(aString,            {"__builtins__":{'True':True,'False':False,'None':None}},            {'null':None,'true':True,'false':False})        except NameError:            raise ReadException, \            "Strings must be quoted. Could not read '%s'." % aString        except SyntaxError:            raise ReadException, \            "Syntax error.  Could not read '%s'." % aString        return result# badOperators is defined at the top of the module# generate the regexes for math detectionregexes = {}for operator in badOperators:    if operator in '+*':        # '+' and '*' need to be escaped with \ in re        regexes[operator,'numeric operation'] \        = compile(r"\d*\s*\%s|\%s\s*\d*" % (operator, operator))    else:        regexes[operator,'numeric operation'] \        = compile(r"\d*\s*%s|%s\s*\d*" % (operator, operator))def _getStringState(aSequence):    """return the list of required quote closures if the end of aString needs them    to close quotes.    """    state = []    for k in aSequence:        if k in ['"',"'"]:            if state and k == state[-1]:                state.pop()            else:                state.append(k)    return statedef _sanityCheckMath(aString):    """just need to check that, if there is a math operator in the       client's JSON, it is inside a quoted string. This is mainly to       keep client from successfully sending 'D0S'*9**9**9**9...       Return True if OK, False otherwise    """    for operator in badOperators:        #first check, is it a possible math operation?        if regexes[(operator,'numeric operation')].search(aString) is not None:            # OK.  possible math operation. get the operator's locations            getlocs = regexes[(operator,'numeric operation')].finditer(aString)            locs = [item.span() for item in getlocs]            halfStrLen = len(aString) / 2            #fortunately, this should be rare            for loc in locs:                exprStart = loc[0]                exprEnd = loc[1]                # We only need to know the char is within open quote                # status.                if exprStart <= halfStrLen:                    teststr = aString[:exprStart]                else:                    teststr = list(aString[exprEnd+1:])                    teststr.reverse()                if not _getStringState(teststr):                    return False    return Truedef safeRead(aString):    """turn the js into happier python and check for bad operations       before sending it to the interpreter    """    # get rid of trailing null. Konqueror appends this, and the python    # interpreter balks when it is there.    CHR0 = chr(0)    while aString.endswith(CHR0):        aString = aString[:-1]    # strip leading and trailing whitespace    aString = aString.strip()    # zap /* ... */ comments    aString = slashstarcomment.sub('',aString)    # zap // comments    aString = doubleslashcomment.sub('',aString)    # here, we only check for the * operator as a DOS problem by default;    # additional operators may be excluded by editing badOperators    # at the top of the module    if _sanityCheckMath(aString):        return _Read(aString)    else:        raise ReadException, 'Unacceptable JSON expression: %s' % aStringread = safeRead##################################   write object as JSON        ###################################alwaysStripWhiteSpace is defined at the top of the moduletfnTuple = (('True','true'),('False','false'),('None','null'),)def _replaceTrueFalseNone(aString):    """replace True, False, and None with javascript counterparts"""    for k in tfnTuple:        if k[0] in aString:            aString = aString.replace(k[0],k[1])    return aStringdef _handleCode(subStr,stripWhiteSpace):    """replace True, False, and None with javascript counterparts if       appropriate, remove unicode u's, fix long L's, make tuples       lists, and strip white space if requested    """    if 'e' in subStr:        #True, False, and None have 'e' in them. :)        subStr = (_replaceTrueFalseNone(subStr))    if stripWhiteSpace:        # re.sub might do a better job, but takes longer.        # Spaces are the majority of the whitespace, anyway...        subStr = subStr.replace(' ','')    if subStr[-1] in "uU":        #remove unicode u's        subStr = subStr[:-1]    if "L" in subStr:        #remove Ls from long ints        subStr = subStr.replace("L",'')    #do tuples as lists    if "(" in subStr:        subStr = subStr.replace("(",'[')    if ")" in subStr:        subStr = subStr.replace(")",']')    return subStr# re for a double-quoted string that has a single-quote in it# but no double-quotes and python punctuation after:redoublequotedstring = compile(r'"[^"]*\'[^"]*"[,\]\}:\)]')escapedSingleQuote = r"\'"escapedDoubleQuote = r'\"'def doQuotesSwapping(aString):    """rewrite doublequoted strings with single quotes as singlequoted strings with    escaped single quotes"""    s = []    foundlocs = redoublequotedstring.finditer(aString)    prevend = 0    for loc in foundlocs:        start,end = loc.span()        s.append(aString[prevend:start])        tempstr = aString[start:end]        endchar = tempstr[-1]        ts1 = tempstr[1:-2]        ts1 = ts1.replace("'",escapedSingleQuote)        ts1 = "'%s'%s" % (ts1,endchar)        s.append(ts1)        prevend = end    s.append(aString[prevend:])    return ''.join(s)def _pyexpr2jsexpr(aString, stripWhiteSpace):    """Take advantage of python's formatting of string representations of    objects.  Python always uses "'" to delimit strings.  Except it doesn't when    there is ' in the string.  Fix that, then, if we split    on that delimiter, we have a list that alternates non-string text with    string text.  Since string text is already properly escaped, we    only need to replace True, False, and None in non-string text and    remove any unicode 'u's preceding string values.    if stripWhiteSpace is True, remove spaces, etc from the non-string    text.    """    inSingleQuote = False    inDoubleQuote = False    #python will quote with " when there is a ' in the string,    #so fix that first    if redoublequotedstring.search(aString):        aString = doQuotesSwapping(aString)    marker = None    if escapedSingleQuote in aString:        #replace escaped single quotes with a marker        marker = markerBase = '|'        markerCount = 1        while marker in aString:            #if the marker is already there, make it different            markerCount += 1            marker = markerBase * markerCount        aString = aString.replace(escapedSingleQuote,marker)    #escape double-quotes    aString = aString.replace('"',escapedDoubleQuote)    #split the string on the real single-quotes    splitStr = aString.split("'")    outList = []    alt = True    for subStr in splitStr:        #if alt is True, non-string; do replacements        if alt:            subStr = _handleCode(subStr,stripWhiteSpace)        outList.append(subStr)        alt = not alt    result = '"'.join(outList)    if marker:        #put the escaped single-quotes back as "'"        result = result.replace(marker,"'")    return resultdef write(obj, encoding="utf-8",stripWhiteSpace=alwaysStripWhiteSpace):    """Represent the object as a string.  Do any necessary fix-ups    with pyexpr2jsexpr"""    try:        #not really sure encode does anything here        aString = str(obj).encode(encoding)    except UnicodeEncodeError:        aString = obj.encode(encoding)    if isinstance(obj,basestring):        if '"' in aString:            aString = aString.replace(escapedDoubleQuote,'"')            result = '"%s"' % aString.replace('"',escapedDoubleQuote)        else:            result = '"%s"' % aString    else:        result = _pyexpr2jsexpr(aString,stripWhiteSpace).encode(encoding)    return resultclass ReadException(Exception):    passclass WriteException(Exception):    pass
0 0