Неправильный вывод с использованием примера кода из онлайн-книги

1

У меня возникают проблемы с этим кодом Python. Он должен давать мне вывод, аналогичный показанному здесь (должен отличаться для разных музыкальных файлов):

    album=
    artist=Ghost in the Machine
    title=A Time Long Forgotten (Concept
    genre=31
    name=/music/_singles/a_time_long_forgotten_con.mp3
    year=1999
    comment=http://mp3.com/ghostmachine

Но вместо этого дает мне следующее:

name = derp/whoshotya.mp3

Вот код, приведенный мне (слегка модифицированный для размещения используемого мной музыкального образца) в главе 5 Dive Into Python, который можно найти здесь:

"""Framework for getting filetype-specific metadata.

Instantiate appropriate class with filename.  Returned object acts like a dictionary, with key-value pairs for each piece of metadata.

import fileinfo
info = fileinfo.MP3FileInfo("/music/ap/mahadeva.mp3")
print "\\n".join(["%s=%s" % (k, v) for k, v in info.items()])

Или используйте функцию listDirectory, чтобы получить информацию обо всех файлах в каталоге.

for info in fileinfo.listDirectory("/music/ap/", [".mp3"]):
    ...

Framework можно расширить, добавив классы для определенных типов файлов, например. HTMLFileInfo, MPGFileInfo, DOCFileInfo. Каждый класс несет полную ответственность за правильная обработка файлов; см. MP3FileInfo, например.

Эта программа является частью "Dive Into Python", бесплатной книги Python для опытных программистов. Посетите http://diveintopython.net/ для последней версии.

"""

__author__ = "Mark Pilgrim ([email protected])"
__version__ = "$Revision: 1.3 $"
__date__ = "$Date: 2004/05/05 21:57:19 $"
__copyright__ = "Copyright (c) 2001 Mark Pilgrim"
__license__ = "Python"

import os
import sys
from UserDict import UserDict

def stripnulls(data):
    "strip whitespace and nulls"
    return data.replace("\00", " ").strip()

class FileInfo(UserDict):
    "store file metadata"
    def __init__(self, filename=None):
        UserDict.__init__(self)
        self["name"] = filename

class MP3FileInfo(FileInfo):
    "store ID3v1.0 MP3 tags"
    tagDataMap = {"title"   : (  3,  33, stripnulls),
                  "artist"  : ( 33,  63, stripnulls),
                  "album"   : ( 63,  93, stripnulls),
                  "year"    : ( 93,  97, stripnulls),
                  "comment" : ( 97, 126, stripnulls),
                  "genre"   : (127, 128, ord)}

    def __parse(self, filename):
        "parse ID3v1.0 tags from MP3 file"
        self.clear()
        try:
            fsock = open(filename, "rb", 0)
            try:
                fsock.seek(-128, 2)
                tagdata = fsock.read(128)
            finally:
                fsock.close()
            if tagdata[:3] == 'TAG':
                for tag, (start, end, parseFunc) in self.tagDataMap.items():
                    self[tag] = parseFunc(tagdata[start:end])
        except IOError:
            pass

    def __setitem__(self, key, item):
        if key == "name" and item:
            self.__parse(item)
        FileInfo.__setitem__(self, key, item)

def listDirectory(directory, fileExtList):
    "get list of file info objects for files of particular extensions"
    fileList = [os.path.normcase(f) for f in os.listdir(directory)]
    fileList = [os.path.join(directory, f) for f in fileList \
                if os.path.splitext(f)[1] in fileExtList]
    def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]):
        "get file info class from filename extension"
        subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:]
        return hasattr(module, subclass) and getattr(module, subclass) or FileInfo
    return [getFileInfoClass(f)(f) for f in fileList]

if __name__ == "__main__":
    for info in listDirectory("derp/", [".mp3"]):
        print "\n".join(["%s=%s" % (k, v) for k, v in info.items()])
        print
  • 1
    пожалуйста, сделайте отступ в коде правильно, проверьте синтаксические ошибки и используйте теги кода.
Теги:

1 ответ

0
Лучший ответ

Я думаю, проблема может быть здесь:

if __name__ == "__main__":
    for info in listDirectory("derp/", [".mp3"]):
        print "\n".join(["%s=%s" % (k, v) for k, v in info.items()])
        print

Моя мысль заключается в том, что в файле (info) нет всех тегов файлов, заполненных, как в примере. Вот почему это только показывает поле имени. Попробуйте вручную изменить теги файлов (щелкнув правой кнопкой мыши файл и перейдите к свойствам) и снова запустите функцию.

EDIT: Я не уверен, что происходит в вашем коде, но у меня есть теория.

class MP3FileInfo(FileInfo):
    ...
    def __setitem__(self, key, item):
        if key == "name" and item:
            self.__parse(item)
        FileInfo.__setitem__(self, key, item)

Эта часть меня сбивает с толку. Что именно здесь происходит? Казалось бы, вы захотите добавить анализируемые данные в объект FileInfo, не так ли? Откуда эта функция вызвана? И ключ всегда будет чем-то другим, кроме "имени", потому что это может быть вашей проблемой.

  • 0
    Это хороший момент, хотя я проверил это. Некоторые поля определенно заполнены, и если вы посмотрите на «ожидаемый результат», который он дает, некоторые поля отображаются, даже если они пусты.
  • 0
    Кроме того, я изменил некоторые поля, чтобы убедиться, что это не проблема, и я все еще получаю ту же проблему.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню