为什么Python 3 json.loads(“ foo.com”)不能正常工作,而json.loads(“ 123.6”)可以呢?

时间:2018-11-15 21:17:59

标签: json python-3.x

当我尝试加载“ foo.com”时,出现异常,正如预期的那样;但是,如果我正在加载包含浮点数的字符串,则它可以工作。只是想弄清楚为什么会这样。

$ python3
Python 3.6.5 (default, Jun 17 2018, 12:13:06)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> j = json.loads("foo.com")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
>>> j = json.loads("123.6")
>>>

2 个答案:

答案 0 :(得分:2)

RFC7159中定义JSON的报价:

  

这些是六个结构特征:

 begin-array     = ws %x5B ws  ; [ left square bracket
 begin-object    = ws %x7B ws  ; { left curly bracket
 end-array       = ws %x5D ws  ; ] right square bracket
 end-object      = ws %x7D ws  ; } right curly bracket
 name-separator  = ws %x3A ws  ; : colon
 value-separator = ws %x2C ws  ; , comma
     

JSON值必须是对象,数组,数字或字符串,或以下之一      以下三个文字名称:

false null true
     

<...>不允许使用其他文字名称。

value = false / null / true / object / array / number / string
object = begin-object [ member *( value-separator member ) ]
           end-object
array = begin-array [ value *( value-separator value ) ] end-array
number = [ minus ] int [ frac ] [ exp ]
string = quotation-mark *char quotation-mark

如您所见,输入foo.com不满足以下任何条件:

  • 它不是以begin-object开头
  • 它也不以begin-array
  • 开头
  • 也不是数字
  • 它也不是字符串,因为它不是quotation-mark开头

但是,123.6是一个数字:

123 . 6 == int frac

其中,根据RFC:

frac = decimal-point 1*DIGIT
int = zero / ( digit1-9 *DIGIT )

因此,123 . 6value,所以很好。

答案 1 :(得分:1)

json.loads需要一个字符串。当JSON解析器处理此字符串时,剩下的全部是foo.com,这是无效的令牌。这是该示例的一个极端情况:

json.loads('{a: 1}')

您不会指望它起作用,不是吗? a是无效的令牌。

要执行此操作,我们将需要另一组引号:

print(json.loads('"foo.com"'))
# foo.com