我很困惑为什么在尝试从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')
答案 0 :(得分:7)
你的问题是,当json
模块解析一个JSON对象时,它会返回一个Python dict
- 这是Python中用于手头数据的更合适的数据结构。
这意味着您不想尝试访问其中的字段,而是访问dict
中的项目。用于访问dict
s(或dict
- 类对象)项的Python语法是:
dict[name]
所以在你的情况下:
new_story['title']
有关详细信息,请参阅the documentation for dict
s。
如果密钥不存在,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)
...
答案 1 :(得分:0)
因为你必须使用new_story ['title'],但是如果这个键不存在,它会抛出异常
答案 2 :(得分:0)
除了 Lattyware的答案:为了能够使用.some_attribute
约定访问dict,你可以使用一个技巧:
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。