python json 字典直接访问

1 投票
3 回答
4206 浏览
提问于 2025-04-17 15:16

我有点困惑,为什么在从一个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')

3 个回答

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

0

因为你需要使用 new_story['title'],但是如果这个键不存在,就会出现错误。

7

你的问题是,当json模块解析一个JSON对象时,它会返回一个Python的dict(字典)——这在Python中是处理这种数据的更合适的数据结构。

这意味着你不应该直接去访问它的字段,而是应该访问这个dict中的项目。访问dict(或类似字典的对象)中的项目的Python语法是:

dict[name]

所以在你的情况下:

new_story['title']

想了解更多信息,可以查看关于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)
    ...

撰写回答