0

我有一段代码使用我命名的函数从ticketmaster API 获取数据get_event_info。代码的第一个版本按预期工作,随后我修改了原始函数以使用基于标头的身份验证而不是基于 URL。我还在函数中添加了几行代码,用于验证响应状态代码。进行这些更改后,代码开始生成以下内容TypeError

Traceback (most recent call last):
  File "ticketmaster_only_w_headers.py", line 146, in <module>
    for event in ticket_search["_embedded"]["events"].items():
TypeError: 'NoneType' object is not subscriptable

我已经阅读了很多关于此类错误的信息,但我仍然无法确定为什么我的代码会在这种情况下产生它。我非常感谢您解释为什么我的代码会产生此错误以及我应该使用哪些故障排除方法来发现源错误。我对编程相当熟悉,但肯定不是专家,所以语言越简单越好。

(功能定义)

def get_event_info(search):
    if search in CACHE_DICTION:
        d = CACHE_DICTION[search]
    else:
        api_url = '{0}events/'.format(api_url_base)        
        payload = {"keyword": search, "apikey": api_token,
                   "format": "json", "dmaId": "366", "size": 200, "radius": "2"}
        response = requests.get(api_url, headers=headers, params=payload)
        if response.status_code == 200:
            d = json.loads(response.text)
            CACHE_DICTION[search] = d
            f = open(CACHE_FNAME, 'w')
            f.write(json.dumps(CACHE_DICTION))
            f.close()
        else:
            d = None
    return d

(触发错误的代码片段)

ticket_search = get_event_info("")

for event in ticket_search["_embedded"]["events"]:
    a = event["id"]
    b = event["name"]
    if "dateTime" in event["dates"]["start"]:
        c = event["dates"]["start"]["dateTime"].replace(
            "T", " ").replace("Z", "")
    else:
        c = "NONE"
    if "end" in event["dates"] and "dateTime" in event["dates"]["end"]:
        j = event["dates"]["end"]["dateTime"].replace(
            "T", " ").replace("Z", "")
    else:
        j = "NONE"

(创建、打开和写入上述代码中使用的缓存的代码)


CACHE_FNAME = "ticketmaster_cache.json"                                         
try:
    cache_file = open(CACHE_FNAME, "r")                                         
    cache_contents = cache_file.read()                                          
    CACHE_DICTION = json.loads(cache_contents)                                  
    cache_file.close()                                                          
except:
    CACHE_DICTION = {}

下面显示的函数的先前版本get_event_info不产生任何TypeError

def get_event_info(search, ticketmaster_key = ticketmaster_key):                                                                                
    if search in CACHE_DICTION:                                         
        d = CACHE_DICTION[search]
    else:                                                                       
        data = requests.get("https://app.ticketmaster.com/discovery/v2/events", 
            params = {"keyword": search, "apikey": ticketmaster_key,            
            "format":"json", "dmaId": "366", "size": 200, "radius": "2"})
        print(data.url)
        d = json.loads(data.text)                                       
        CACHE_DICTION[search] = d                                      
        f = open(CACHE_FNAME, 'w')                                      
        f.write(json.dumps(CACHE_DICTION))                             
        f.close()                                                       
    return d

运行最新版本的代码时看到的回溯和错误消息:

Traceback (most recent call last):
  File "ticketmaster_only_w_headers.py", line 146, in <module>
    for event in ticket_search["_embedded"]["events"]:
TypeError: 'NoneType' object is not subscriptable
4

2 回答 2

1

每当你有一个可以显式返回的函数时None,你应该总是首先检查返回值:

def func(a):
    if a == 1:
        return list(range(10)) # could return a list
    else:
        return None            # or it could return None

a = 10
f = func(a)

f[1]
# raises TypeError: NoneType is not subscriptable

# check for NoneType first
if f is not None:
    print(f[1])
# otherwise, kick out different result
else:
    print('Got "None" for f!')

# Got "None" for f!

ticket_search的返回为None,但是因为您的for循环正在尝试进行键查找,所以它失败了,因为None不支持该操作。根据上面的逻辑,您的逻辑应如下所示:

if ticket_search is not None:
    for event in ticket_search["_embedded"]["events"]:
        a = event["id"]

else:
    raise TypeError
    # or do something else


于 2019-06-24T01:55:17.087 回答
0

好吧,解释器明确地告诉您,您正在尝试评估诸如a[i], where ais之类的东西None(而不是预期的类型,例如列表或字典)。在您的情况下,它要么是ticket_search它本身,要么是ticket_search["_embedded"].

print(ticket_search)在任何情况下,如果您可以重新运行您的代码,那么在下面放置ticket_search = get_event_info("")应该会让一切变得清晰。

于 2019-06-24T01:51:28.623 回答