1

我很困惑为什么在尝试从 json 文件访问对象数组时必须使用 `.get('key')

req = urllib2.Request("http://website.com/entertainment/entertainment_news.json", None)
opener = urllib2.build_opener()
f = opener.open(req)
stories = json.load(f)
for new_story in stories:
    #Why can't I access variables using
    new_story.title

    #I have to do
    new_story.get('title')
4

3 回答 3

7

您的问题是,当json模块解析 JSON 对象时,它返回一个 Python dict- 这是 Python 中更适合手头数据的数据结构。

这意味着您不想尝试访问其上的字段,而是访问dict. 访问dicts (或类似dict对象)的项目的 Python 语法是:

dict[name]

所以在你的情况下:

new_story['title']

有关更多信息,请参阅s的文档。dict

如果dict.get()密钥None不存在(通常这会产生KeyError一个问题是,None当您尝试使用它时,获得价值并在以后出现错误)。

另请注意,这是该with语句的一个很好的用例,可确保正确关闭连接。由于urllib2默认情况下不支持上下文管理器,我们使用它contextlib.closing()来制作:

from contextlib import closing
req = urllib2.Request("http://website.com/entertainment/entertainment_news.json", None)
opener = urllib2.build_opener()
with closing(opener.open(req)) as f:
    stories = json.load(f)
    ...
于 2013-02-08T17:52:10.440 回答
0

因为你必须使用 new_story['title'],但是如果这个键不存在,它会抛出异常

于 2013-02-08T17:52:11.613 回答
0

除了Lattyware 的回答:为了能够使用.some_attribute约定访问字典,您可以使用一个技巧:

class Story:
  def __init__(self, **kwargs):
    self.__dict__.update(kwargs)

#...    
stories = [Story(story) for story in json.load(f)]
for new_story in stories:
    # now you can do it!
    new_story.title

...尽管如果您真的想坚持使用“点”表示法,它会这样做。它只会给您的程序带来另一个复杂性(除了许多其他缺点,例如story.title.somethingelse在没有一些递归初始化的情况下将无法在这个简单的场景中工作)

您也可以考虑使用namedtuple

于 2013-02-08T18:07:50.337 回答