<< >>

diveintopython.org |

Python for experienced programmers

## 第三章 面向对象框架

目录

- 3.1. 接触
- 3.2. 定义类
- 3.3. 类的实例化
- 3.4. `UserDict`: 一个封装类
- 3.5. 专用类方法
- 3.6. 高级专用类方法
- 3.7. 类属性
- 3.8. 私有函数
- 3.9. 处理异常
- 3.10. 文件对象
- 3.11. `for` 循环
- 3.12. 一次赋多个值
- 3.13. 更多关于模块

## 3.1. 接触

这一章，和此后的许多章，均讨论了面向对象的Python程序设计。还记得我说过你应该知道一门面向对象语言来阅读这本书吗？哦，我可不是开完笑。

下面是一个完整的，可运行的Python程序。阅读模块，类，和函数的文档字符串，可以了解这个程序所做的和如何工作的总体印象。

例 3.1. `fileinfo.py`

    """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()])

    Or use listDirectory function to get info on all files in a directory.
        for info in fileinfo.listDirectory("/music/ap/", [".mp3"]):
            ...

    Framework can be extended by adding classes for particular file types, e.g.
    HTMLFileInfo, MPGFileInfo, DOCFileInfo.  Each class is completely responsible for
    parsing its files appropriately; see MP3FileInfo for example.
    """
    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"
        fileExtList = [ext.upper() for ext in fileExtList]
        fileList = [os.path.join(directory, f) for f in os.listdir(directory) \
                    if os.path.splitext(f)[1].upper() 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("/music/_singles/", [".mp3"]):
            print "\n".join(["%(key)s=%(value)s" % vars() for key, value in info.items()])
            print

| 这个程序的输出要依赖于你硬盘上的文件。为了得到有意义的输出，你应该修改目录路径指到你自已机器上的一个MP3文件目录。

例 3.2. `fileinfo.py` 的输出

下面就是从我的机器上得到的输出。你的输出将不一样，除非，由于某些令人吃惊的巧合，你与我有着共同的音乐品味。

    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

    album=Rave Mix
    artist=***DJ MARY-JANE***
    title=HELLRAISER****Trance from Hell
    genre=31
    name=/music/_singles/hellraiser.mp3
    year=2000
    comment=http://mp3.com/DJMARYJANE

    album=Rave Mix
    artist=***DJ MARY-JANE***
    title=KAIRO****THE BEST GOA
    genre=31
    name=/music/_singles/kairo.mp3
    year=2000
    comment=http://mp3.com/DJMARYJANE

    album=Journeys
    artist=Masters of Balance
    title=Long Way Home
    genre=31
    name=/music/_singles/long_way_home1.mp3
    year=2000
    comment=http://mp3.com/MastersofBalan

    album=
    artist=The Cynic Project
    title=Sidewinder
    genre=18
    name=/music/_singles/sidewinder.mp3
    year=2000
    comment=http://mp3.com/cynicproject

    album=Digitosis@128k
    artist=VXpanded
    title=Spinning
    genre=255
    name=/music/_singles/spinning.mp3
    year=2000
    comment=http://mp3.com/artists/95/vxp

« 小结 | 定义类 »