如何解决使用Spotipy / Spotify API的“其他”序列问题
我和我的团队(python的新手)编写了以下代码,以生成与特定城市和相关术语相关的Spotify歌曲。 如果用户输入的城市不在我们的CITY_KEY_WORDS列表中,则它告诉用户输入将被添加到请求文件中,然后将输入写入文件中。 代码如下:
from random import shuffle
from typing import Any,Dict,List
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
sp = spotipy.Spotify(
auth_manager=SpotifyClientCredentials(client_id="",client_secret="")
)
CITY_KEY_WORDS = {
'london': ['big ben','fuse'],'paris': ['eiffel tower','notre dame','louvre'],'manhattan': ['new york','new york city','nyc','empire state','wall street',],'rome': ['colosseum','roma','spanish steps','pantheon','sistine chapel','vatican'],'berlin': ['berghain','berlin wall'],}
def main(city: str,num_songs: int) -> List[Dict[str,Any]]:
if city in CITY_KEY_WORDS:
"""Searches Spotify for songs that are about `city`. Returns at most `num_songs` tracks."""
results = []
# Search for songs that have `city` in the title
results += sp.search(city,limit=50)['tracks']['items'] # 50 is the maximum Spotify's API allows
# Search for songs that have key words associated with `city`
if city.lower() in CITY_KEY_WORDS.keys():
for related_term in CITY_KEY_WORDS[city.lower()]:
results += sp.search(related_term,limit=50)['tracks']['items']
# Shuffle the results so that they are not ordered by key word and return at most `num_songs`
shuffle(results)
return results[: num_songs]
else:
print("Unfortunately,this city is not yet in our system. We will add it to our requests file.")
with open('requests.txt','r') as text_file:
request = text_file.read()
request = request + city + '\n'
with open('requests.txt','w+') as text_file:
text_file.write(request)
def display_tracks(tracks: List[Dict[str,Any]]) -> None:
"""Prints the name,artist and URL of each track in `tracks`"""
for num,track in enumerate(tracks):
# Print the relevant details
print(f"{num + 1}. {track['name']} - {track['artists'][0]['name']} {track['external_urls']['spotify']}")
if __name__ == '__main__':
city = input("Virtual holiday city? ")
number_of_songs = input("How many songs would you like? ")
tracks = main(city,int(number_of_songs))
display_tracks(tracks)
对于“ if”语句,该代码运行良好(如果有人进入我们列出的城市)。 但是在运行else语句时,在执行完确定的操作后会出现2个错误(它将打印用户的输入并将其写入文件)。
出现的错误是:
Traceback (most recent call last):
File "...",line 48,in <module>
display_tracks(tracks)
File "...",line 41,in display_tracks
for num,track in enumerate(tracks):
TypeError: 'nonetype' object is not iterable
请原谅我缺乏知识,但是请有人可以帮助解决这个问题吗?
我们也想在最后创建歌曲的播放列表,但是在此方面一直面临困难。
解决方法
在执行if
语句时,您将返回一个项目列表,并将其馈送到display_tracks()
函数中。但是执行else
语句后会发生什么?您可以将请求添加到文本文件中,但不返回任何内容(或NoneType
项目)并将其输入display_tracks()
中。 display_tracks
然后对此NoneType
项进行迭代,并引发异常。
您只想在实际有任何曲目要显示的情况下显示曲目。一种实现方法是将对display_tracks()
的调用移到您的main
函数中,但是如果未在搜索条件中找到任何曲目,则会引发相同的错误。另一个解决方案是首先检查您的tracks
是否为空,或者使用类似的
TypeError
异常。
tracks = main(city,int(number_of_songs))
try:
display_tracks(tracks)
except TypeError:
pass
,
您的main
函数在return
子句中没有else
语句,这导致tracks
为None
。导致错误的是在tracks
上对None
进行迭代。
您可以采取一些措施来改善代码:
- 关注点分离:
main
函数正在做两种不同的事情,检查输入并获取轨道。 - 一开始只做一次
.lower()
,所以您不必重复。 - 遵循文档约定。
- 在使用前检查响应
- 一些代码清除
请参见下面我上面建议的更改:
def fetch_tracks(city: str,num_songs: int) -> List[Dict[str,Any]]:
"""Searches Spotify for songs that are about `city`.
:param city: TODO: TBD
:param num_songs: TODO: TBD
:return: at most `num_songs` tracks.
"""
results = []
for search_term in [city,*CITY_KEY_WORDS[city]]:
response = sp.search(search_term,limit=50)
if response and 'tracks' in response and 'items' in response['tracks']:
results += response['tracks']['items']
# Shuffle the results so that they are not ordered by key word and return
# at most `num_songs`
shuffle(results)
return results[: num_songs]
def display_tracks(tracks: List[Dict[str,Any]]) -> None:
"""Prints the name,artist and URL of each track in `tracks`"""
for num,track in enumerate(tracks):
# Print the relevant details
print(
f"{num + 1}. {track['name']} - {track['artists'][0]['name']} "
f"{track['external_urls']['spotify']}")
def main():
city = input("Virtual holiday city? ")
city = city.lower()
# Check the input city and handle unsupported cities.
if city not in CITY_KEY_WORDS:
print("Unfortunately,this city is not yet in our system. "
"We will add it to our requests file.")
with open('requests.txt','a') as f:
f.write(f"{city}\n")
exit()
number_of_songs = input("How many songs would you like? ")
tracks = fetch_tracks(city,int(number_of_songs))
display_tracks(tracks)
if __name__ == '__main__':
main()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。