【问题标题】:'unicode' object has no attribute 'keys' - convert object to dictionary python'unicode' 对象没有属性 'keys' - 将对象转换为字典 python
【发布时间】:2021-06-17 13:46:16
【问题描述】:

问题

我正在尝试将对象转换为 dict 以创建 sqlite 数据库。我正在使用一个名为“tinytag”的应用程序从计算机上的 mp4 中提取元数据。

当我运行该函数时,我得到一个看起来像密钥对但它们是一个对象的数据列表。我尝试使用我在网上找到的一些代码将变量转换为字典,但它会拉出一个我不确定的错误。

这是我的代码:

import os
import subprocess
from tinytag import TinyTag
import sqlite3
import json


tag = ''
extf = ['$RECYCLE.BIN','System Volume Information']
for root, dirs, files in os.walk(r'\\Vgmstation\\e\\', followlinks=True):
    dirs[:] = [d for d in dirs if d not in extf]
    for name in files:
        if name.endswith(".mp4"):
            musiclist=str(os.path.join(root, name)) 
            tag = TinyTag.get(musiclist)
            tag_str = str(tag)
            tag_json = json.loads(json.dumps(tag_str, default=lambda o: o.__dict__))

            
conn = sqlite3.connect('musicdatabase.db')
c = conn.cursor()

for tablist in tag_json.keys():
    fieldset = []
    for col, definition in tag_json[tablist].items():
        fieldset.append("'{0}' {1}".format(col, definition))

    if len(fieldset) > 0:
        query = "CREATE TABLE IF NOT EXISTS {0} ({1})".format(tablist, ", ".join(fieldset))

        c.execute(query)

c.close()
conn.close()

如果我打印它,tag = TinyTag.get(musiclist) 是这样的:

{"album": "Final Fantasy VII", "albumartist": "Nobuo Uematsu", "artist": "Nobuo Uematsu", "audio_offset": null, "bitrate": 294651.393, "channels": 2, "comment": "Role-playing Game", "composer": "Nobuo Uematsu", "disc": null, "disc_total": null, "duration": 350.08306666666664, "filesize": 575693062, "genre": null, "samplerate": 48000, "title": "Full-Scale Attack", "track": null, "track_total": null, "year": "1997"}
{"album": "Final Fantasy VII", "albumartist": "Nobuo Uematsu", "artist": "Nobuo Uematsu", "audio_offset": null, "bitrate": 294651.393, "channels": 2, "comment": "Role-playing Game", "composer": "Nobuo Uematsu", "disc": null, "disc_total": null, "duration": 111.07763333333334, "filesize": 179760044, "genre": null, "samplerate": 48000, "title": "Gold Saucer", "track": null, "track_total": null, "year": "1997"}
{"album": "Final Fantasy VII", "albumartist": "Nobuo Uematsu", "artist": "Nobuo Uematsu", "audio_offset": null, "bitrate": 294651.393, "channels": 2, "comment": "Role-playing Game", "composer": "Nobuo Uematsu", "disc": null, "disc_total": null, "duration": 195.06153333333333, "filesize": 318267268, "genre": null, "samplerate": 48000, "title": "Great Warrior", "track": null, "track_total": null, "year": "1997"}
{"album": "Final Fantasy VII", "albumartist": "Nobuo Uematsu", "artist": "Nobuo Uematsu", "audio_offset": null, "bitrate": 294651.393, "channels": 2, "comment": "Role-playing Game", "composer": "Nobuo Uematsu", "disc": null, "disc_total": null, "duration": 222.08853333333334, "filesize": 363059333, "genre": null, "samplerate": 48000, "title": "Hollding My Thoughts in My heart", "track": null, "track_total": null, "year": "1997"}
# over 6000 more songs left ...

结果如下:

Traceback (most recent call last):
  File "//VGMSTATION/testing scripts/search and print2.py", line 35, in <module>
    for tablist in tag_json.keys():
AttributeError: 'unicode' object has no attribute 'keys'

我尝试查找但没有帮助或我不明白的内容:AttributeError: 'unicode' object has no attribute 'key' 'unicode' object has no attribute 'keys'

【问题讨论】:

  • 听起来您可能正在处理元组。你能展示一些应用程序的输出示例吗?
  • 你试过print(tag_json)看看是什么吗?您可能更倾向于自己调试;)
  • @norie - 我更新了问题以显示如果我打印 tag = TinyTag.get(musiclist) 输出的样子
  • @azro - 我尝试打印 print(tag_json),它给了我输出的其中一行,我试图将其转换为字典 {"album": "Spawn Armageddon", "albumartist": "Rik Schaffer", "artist": "Rik Schaffer", "audio_offset": null, "bitrate": 294651.393, "channels": 2, "comment": "Action-adventure", "composer": "Rik Schaffer", "disc": null, "disc_total": null, "duration": 49.11573333333333, "filesize": 75479673, "genre": null, "samplerate": 48000, "title": null, "track": "9", "track_total": "0", "year": "2003"}
  • 如果使用 tag 而不是 tag_json 创建字典会怎样?

标签: python json dictionary


【解决方案1】:

查看 json 文件的解码以及访问键和值。我创建了一个例子

import json

with open("example.json") as tag_json:  
    # json decoding
    data = json.load(tag_json)
    
    keys = data.keys()
    values = data.values()

print(keys, values)

"""prints dict_keys(['Emp_Info']) dict_values([[{'name': 'a', 'id': '123'}, {'name': 'b', 'id': '345'}]])"""

#access Keys
tag_data = data['Emp_Info'] #

for x in tag_data:
    print(x.keys(), x.values())

"""
dict_keys(['name', 'id']) dict_values(['a', '123'])
dict_keys(['name', 'id']) dict_values(['b', '345'])
"""

【讨论】:

    【解决方案2】:

    您对TinyTag.get 输出所做的事情:

    tag = TinyTag.get(musiclist)
    tag_str = str(tag)
    tag_json = json.loads(json.dumps(tag_str, default=lambda o: o.__dict__))
    

    没有意义。您正在调用 str,生成一个字符串,然后 JSON 转储 字符串,然后加载 JSON,将您的字符串返回给您。转储/加载步骤完全没有意义,最初的str 会适得其反。

    (我怀疑导致你走到这一步的部分原因是这个库使用的可怕的 __str__/__repr__ 实现,这使得它的对象看起来已经是 dicts 或某种 JSON。它们是不是。)

    要将 TinyTag 对象转换为 dict,请调用其 as_dict 方法:

    tag_dict = TinyTag.get(musiclist).as_dict()
    

    (我必须阅读源代码才能发现——这个模块的文档很少。如果你想坚持文档化的界面,你必须手动将所有文档化的属性打包到一个字典中,但是在这一点,你还不如直接使用对象而不用dict转换。)

    【讨论】:

      猜你喜欢
      • 2013-12-28
      • 2011-11-26
      • 1970-01-01
      • 2021-07-26
      • 2019-09-30
      • 2021-01-15
      • 2021-08-09
      • 1970-01-01
      相关资源
      最近更新 更多