YAML 保存和检索

YAML Saving and Retrieving

我正在为 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

后来当我尝试使用 !playlist 时,它的代码是

 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' object 不可订阅

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

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

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

我没有发现您使用 mapping/dict 作为数据结构有什么特别的问题。尽管如果值的键始终是具有递增值的整数,您不妨将其写成 sequence/list.