YAML保存和检索

时间:2016-01-18 12:15:05

标签: python-3.x pyyaml

我正在为Discord开发机器人。问题是我正在使用ffprobe来获取文件夹中所有歌曲的标题和艺术家。现在,我想将此信息保存到YAML文件中,以便我可以在用户输入!playlist后快速检索它。这是我目前的代码。

 # Music Player codes---------------
    if message.content.startswith('!load'.format(self.user.mention)):
        await self.send_message(message.channel, 'Hooked to the voice channel. Please wait while'
                                                 ' I populate the list of songs.')

        global player
        global voice_stream

        if self.is_voice_connected():
            await self.send_message(message.channel,
                                    '```Discord API doesnt let me join multiple servers at the moment.```')

        else:
            voice_stream = await self.join_voice_channel(message.author.voice_channel)

        # TODO get a better way to store local playlist
        try:
            ids = 0
            global s_dict
            s_list = []
            s_playlist = []
            a = glob.glob('./audio_library/*.mp3')
            for a in a:
                try:
                    b = a.replace('\\', '/')
                    ids += 1
                    s_list.append(ids)
                    s_list.append(b)
                    print(b)
                    p = sp.Popen(['ffprobe', '-v', 'quiet', '-print_format', 'json=compact=1', '-show_format',
                                  b], stdout=sp.PIPE, stderr=sp.PIPE)
                    op = p.communicate()
                    op_json = json.loads(op[0].decode('utf-8'))
                    title = op_json['format']['tags']['title']
                    artist = op_json['format']['tags']['artist']
                    await self.send_message(message.channel,
                                            title + ' - ' + artist + ' (code: **' + str(ids) + '**)')
                    s_playlist.append(ids)
                    s_playlist.append(title + ' - ' + artist)

                except Exception as e:
                    print(str(e))
        except:
            await self.send_message(message.channel,
                                    '```No songs in the directory lol.```')

        s_playlist_dict = dict(s_playlist[i:i + 2] for i in range(0, len(s_playlist), 2))
        with open('./configuration/playListInfo.yaml', 'w') as f2:
            yaml.dump(s_playlist_dict, f2, default_flow_style=False)

        s_dict = dict(s_list[i:i + 2] for i in range(0, len(s_list), 2))
        with open('./configuration/song_list.yaml', 'w') as f1:
            yaml.dump(s_dict, f1, default_flow_style=False)

确定。所以这导致了这样的文件。

1: A Party Song (The Walk of Shame) - All Time Low
2: Therapy - All Time Low
3: Barefoot Blue Jean Night - Jake Owen

后来当我尝试使用!播放列表时,其代码为

 if message.content.startswith('!playlist'):

        try:
            # Loading configurations from config.yaml
            with open('./configuration/playListInfo.yaml', 'r') as f3:
                plist = yaml.load(f3)
            idq = 1
            print(plist[idq])
            plistfinal = ''
            for plist in plist:
                song = plist[idq]
                plistfinal += str(song + str(idq) + '\n')
                idq += 1

            print(plistfinal)

        except Exception as e:
            await self.send_message(message.channel,
                                    '```' + str(e) + '```')

我收到错误' int'对象不可订阅

Ignoring exception in on_message
Traceback (most recent call last):
  File "C:\Users\dell\AppData\Local\Programs\Python\Python35-32\lib\site-    packages\discord\client.py", line 254, in _run_event
    yield from getattr(self, event)(*args, **kwargs)
  File "C:/Users/dell/Desktop/Python Projects/lapzbot/lapzbot.py", line 198, in on_message
song = plist[idq]
TypeError: 'int' object is not subscriptable

存储此信息的最佳方式是什么,以及尽可能干净地检索它?

1 个答案:

答案 0 :(得分:1)

plist既是数据结构的名称(mapping / dict),也是其键的迭代器,因为在for循环plist中不起作用将是一个关键。最好做以下事情:

import ruamel.yaml as yaml

yaml_str = """\
1: A Party Song (The Walk of Shame) - All Time Low
2: Therapy - All Time Low
3: Barefoot Blue Jean Night - Jake Owen
"""

data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)

print(data[1])
print('---')

plistfinal = ''
for idq, plist in enumerate(data):
    song = data[plist]
    plistfinal += (str(song) + str(idq) + '\n')

print(plistfinal)

打印:

A Party Song (The Walk of Shame) - All Time Low
---
A Party Song (The Walk of Shame) - All Time Low0
Therapy - All Time Low1
Barefoot Blue Jean Night - Jake Owen2

我没有看到您使用映射/字典作为数据结构的特定问题。虽然如果值的键总是带有增量值的整数,那么您也可以将其写为序列/列表。