【问题标题】:How to improve repeated use of a try statement in Python?如何改进 Python 中 try 语句的重复使用?
【发布时间】:2014-03-26 21:43:33
【问题描述】:

我正在尝试使用 Python 从包含有关歌曲的元数据的 JSON 对象中提取几个元素。为了测试信息是否可用,我对每个元数据元素都使用了 try 语句。此外,对于稍后需要在程序中进行的一些字符串处理,我将每个值保存在不同的变量中。

关于如何改进以下代码以便不为每个不同的元数据值创建 try/except 语句的任何建议?

if len(r['response']['songs']) is not 0:
    # Request information about the artist
    artist_desc_string = "http://developer.echonest.com/api/v4/artist/terms?api_key="+api_key+\
                         "&name="+artist+"&format=json"
    r2 = requests.get(artist_desc_string).json()

    # Extract information from the song JSON
    try:
        title = r['response']['songs'][0]['title']
    except (IndexError, KeyError):
        title = "NULL"

    try:
        artist_name = r['response']['songs'][0]['artist_name']
    except (IndexError, KeyError):
        artist_name = "NULL"

    try:
        artist_location = r['response']['songs'][0]['artist_location']['location'].replace(',','*')
    except (IndexError, KeyError):
        artist_location = "NULL"

    try:
    ...
    ...

【问题讨论】:

  • 这个问题似乎是题外话,因为它属于codereview.stackexchange.com
  • 如果您只是想处理最后一个元素上的 KeyError,您可以查看 dict.get,但由于您在查找路径的整个长度上捕获任何东西,并不是真的。您可以将路径放在列表中并循环遍历它们,但这只能说更简洁,而且可能更慢。
  • 只是一个观察:您始终可以将 r['response']['songs'][0] 分配给单个变量,看看它是如何重复使用的。

标签: python json error-handling


【解决方案1】:

也许这会有所帮助:

def get_value(d, keys):
    try:
        if keys:
            for i in range(len(keys)):
                key = keys[i]
                return get_value(d[key], keys[i+1:])
        return d
    except (IndexError, KeyError):
        return "Null"


>>> d = {'person': {'name': {'first': 'aamir'}}}
>>> get_value(d, ['person', 'name', 'first'])
aamir

【讨论】:

  • 大声笑与我的回答非常相似(除了更具可读性):) +1
  • @JoranBeasley 我刚刚注意到它:P 我正在编写自己的解决方案。
  • 对你们俩都投了赞成票.. 真的没想到 OP 要求的更深层次的属性,但我喜欢你的解决方案。
  • 查看操作问题代码r['response']['songs'][0]是一个字典,可以存储在单个变量中,该解决方案适用于单个或多个键。
【解决方案2】:

可能是这样的吗?

def get_or_dont(d,list_of_keys):
    d2 = d
    while list_of_keys:
        try:
            d2 = d2[list_of_keys.pop(0)]
            if not list_of_keys: return d2
        except:
            break
    return "Null"

r = {'response':{
'a':5,
'b':{'6':{'5':3}},
'c':[1,2,3]
}}
print get_or_dont(r['response'],["b","6"])

【讨论】:

  • except?皱着眉头。
  • 异常列表很长......基本上任何异常都应该返回“Null”
【解决方案3】:

使用具有所有可能属性的 for 循环...

attribs = {'title': None, 'artist_name':None, 'location': None, 'etc': None} for key in attribs: try: attribs[key] = r['response']['songs'][0][key] except (IndexError, KeyError): attribs[key] = "NULL"

这样你只需要管理字典attribs ...

就抓取意外属性而言,您始终可以获取 JSON 对象的键并在属性中创建更多条目

【讨论】:

  • 这将无法处理像r['response']['songs'][0]['artist_location']['location'] 这样的事情,对吧?
猜你喜欢
  • 2017-11-30
  • 2021-08-08
  • 2010-11-25
  • 2012-11-23
  • 2014-02-03
  • 2018-03-13
  • 2014-06-18
  • 2016-03-07
  • 2020-11-20
相关资源
最近更新 更多