1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
  
     | 
    
      
<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   
      <title>Chapter 5. Objects and Object-Orientation</title>
      <link rel="stylesheet" href="../diveintopython.css" type="text/css">
      <link rev="made" href="mailto:f8dy@diveintopython.org">
      <meta name="generator" content="DocBook XSL Stylesheets V1.52.2">
      <meta name="keywords" content="Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free">
      <meta name="description" content="Python from novice to pro">
      <link rel="home" href="../toc/index.html" title="Dive Into Python">
      <link rel="up" href="../toc/index.html" title="Dive Into Python">
      <link rel="previous" href="../power_of_introspection/summary.html" title="4.9. Summary">
      <link rel="next" href="importing_modules.html" title="5.2. Importing Modules Using from module import">
   </head>
   <body>
      <table id="Header" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td id="breadcrumb" colspan="5" align="left" valign="top">You are here: <a href="../index.html">Home</a> > <a href="../toc/index.html">Dive Into Python</a> > <span class="thispage">Objects and Object-Orientation</span></td>
            <td id="navigation" align="right" valign="top">   <a href="../power_of_introspection/summary.html" title="Prev: “Summary”"><<</a>   <a href="importing_modules.html" title="Next: “Importing Modules Using from module import”">>></a></td>
         </tr>
         <tr>
            <td colspan="3" id="logocontainer">
               <h1 id="logo"><a href="../index.html" accesskey="1">Dive Into Python</a></h1>
               <p id="tagline">Python from novice to pro</p>
            </td>
            <td colspan="3" align="right">
               <form id="search" method="GET" action="http://www.google.com/custom">
                  <p><label for="q" accesskey="4">Find: </label><input type="text" id="q" name="q" size="20" maxlength="255" value=" "> <input type="submit" value="Search"><input type="hidden" name="cof" value="LW:752;L:http://diveintopython.org/images/diveintopython.png;LH:42;AH:left;GL:0;AWFID:3ced2bb1f7f1b212;"><input type="hidden" name="domains" value="diveintopython.org"><input type="hidden" name="sitesearch" value="diveintopython.org"></p>
               </form>
            </td>
         </tr>
      </table>
      <!--#include virtual="/inc/ads" -->
      <div class="chapter" lang="en">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title"><a name="fileinfo"></a>Chapter 5. Objects and Object-Orientation
                  </h2>
               </div>
            </div>
            <div></div>
         </div>
         <div class="toc">
            <ul>
               <li><span class="section"><a href="index.html#fileinfo.divein">5.1. Diving In</a></span></li>
               <li><span class="section"><a href="importing_modules.html">5.2. Importing Modules Using from module import</a></span></li>
               <li><span class="section"><a href="defining_classes.html">5.3. Defining Classes</a></span><ul>
                     <li><span class="section"><a href="defining_classes.html#d0e11720">5.3.1. Initializing and Coding Classes</a></span></li>
                     <li><span class="section"><a href="defining_classes.html#d0e11896">5.3.2. Knowing When to Use self and __init__</a></span></li>
                  </ul>
               </li>
               <li><span class="section"><a href="instantiating_classes.html">5.4. Instantiating Classes</a></span><ul>
                     <li><span class="section"><a href="instantiating_classes.html#d0e12165">5.4.1. Garbage Collection</a></span></li>
                  </ul>
               </li>
               <li><span class="section"><a href="userdict.html">5.5. Exploring UserDict: A Wrapper Class</a></span></li>
               <li><span class="section"><a href="special_class_methods.html">5.6. Special Class Methods</a></span><ul>
                     <li><span class="section"><a href="special_class_methods.html#d0e12822">5.6.1. Getting and Setting Items</a></span></li>
                  </ul>
               </li>
               <li><span class="section"><a href="special_class_methods2.html">5.7. Advanced Special Class Methods</a></span></li>
               <li><span class="section"><a href="class_attributes.html">5.8. Introducing Class Attributes</a></span></li>
               <li><span class="section"><a href="private_functions.html">5.9. Private Functions</a></span></li>
               <li><span class="section"><a href="summary.html">5.10. Summary</a></span></li>
            </ul>
         </div>
         <div class="abstract">
            <p>This chapter, and pretty much every chapter after this, deals with object-oriented <span class="application">Python</span> programming.
            </p>
         </div>
         <div class="section" lang="en">
            <div class="titlepage">
               <div>
                  <div>
                     <h2 class="title"><a name="fileinfo.divein"></a>5.1. Diving In
                     </h2>
                  </div>
               </div>
               <div></div>
            </div>
            <div class="abstract">
               <p>Here is a complete, working <span class="application">Python</span> program.  Read the <a href="../getting_to_know_python/documenting_functions.html" title="2.3. Documenting Functions"><tt class="literal">doc string</tt>s</a> of the module, the classes, and the functions to get an overview of what this program does and how it works.  As usual, don't
                  worry about the stuff you don't understand; that's what the rest of the chapter is for.
               </p>
            </div>
            <div class="example"><a name="d0e11177"></a><h3 class="title">Example 5.1. <tt class="filename">fileinfo.py</tt></h3>
               <p>If you have not already done so, you can <a href="http://diveintopython.org/download/diveintopython-examples-5.4.zip" title="Download example scripts">download this and other examples</a> used in this book.
               </p><pre class="programlisting">
<span class='pystring'>"""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.
"""</span>
<span class='pykeyword'>import</span> os
<span class='pykeyword'>import</span> sys
<span class='pykeyword'>from</span> UserDict <span class='pykeyword'>import</span> UserDict
<span class='pykeyword'>def</span><span class='pyclass'> stripnulls</span>(data):
    <span class='pystring'>"strip whitespace and nulls"</span>
    <span class='pykeyword'>return</span> data.replace(<span class='pystring'>"\00"</span>, <span class='pystring'>""</span>).strip()
<span class='pykeyword'>class</span><span class='pyclass'> FileInfo</span>(UserDict):
    <span class='pystring'>"store file metadata"</span>
    <span class='pykeyword'>def</span><span class='pyclass'> __init__</span>(self, filename=None):
        UserDict.__init__(self)
        self[<span class='pystring'>"name"</span>] = filename
<span class='pykeyword'>class</span><span class='pyclass'> MP3FileInfo</span>(FileInfo):
    <span class='pystring'>"store ID3v1.0 MP3 tags"</span>
    tagDataMap = {<span class='pystring'>"title"</span>   : (  3,  33, stripnulls),
                  <span class='pystring'>"artist"</span>  : ( 33,  63, stripnulls),
                  <span class='pystring'>"album"</span>   : ( 63,  93, stripnulls),
                  <span class='pystring'>"year"</span>    : ( 93,  97, stripnulls),
                  <span class='pystring'>"comment"</span> : ( 97, 126, stripnulls),
                  <span class='pystring'>"genre"</span>   : (127, 128, ord)}
    <span class='pykeyword'>def</span><span class='pyclass'> __parse</span>(self, filename):
        <span class='pystring'>"parse ID3v1.0 tags from MP3 file"</span>
        self.clear()
        <span class='pykeyword'>try</span>:                               
            fsock = open(filename, <span class='pystring'>"rb"</span>, 0)
            <span class='pykeyword'>try</span>:                           
                fsock.seek(-128, 2)        
                tagdata = fsock.read(128)  
            <span class='pykeyword'>finally</span>:                       
                fsock.close()              
            <span class='pykeyword'>if</span> tagdata[:3] == <span class='pystring'>"TAG"</span>:
                <span class='pykeyword'>for</span> tag, (start, end, parseFunc) <span class='pykeyword'>in</span> self.tagDataMap.items():
                    self[tag] = parseFunc(tagdata[start:end])               
        <span class='pykeyword'>except</span> IOError:                    
            <span class='pykeyword'>pass</span>                           
    <span class='pykeyword'>def</span><span class='pyclass'> __setitem__</span>(self, key, item):
        <span class='pykeyword'>if</span> key == <span class='pystring'>"name"</span> <span class='pykeyword'>and</span> item:
            self.__parse(item)
        FileInfo.__setitem__(self, key, item)
<span class='pykeyword'>def</span><span class='pyclass'> listDirectory</span>(directory, fileExtList):                                        
    <span class='pystring'>"get list of file info objects for files of particular extensions"</span>
    fileList = [os.path.normcase(f)
                <span class='pykeyword'>for</span> f <span class='pykeyword'>in</span> os.listdir(directory)]           
    fileList = [os.path.join(directory, f) 
               <span class='pykeyword'>for</span> f <span class='pykeyword'>in</span> fileList
                <span class='pykeyword'>if</span> os.path.splitext(f)[1] <span class='pykeyword'>in</span> fileExtList] 
    <span class='pykeyword'>def</span><span class='pyclass'> getFileInfoClass</span>(filename, module=sys.modules[FileInfo.__module__]):      
        <span class='pystring'>"get file info class from filename extension"</span>                             
        subclass = <span class='pystring'>"%sFileInfo"</span> % os.path.splitext(filename)[1].upper()[1:]       
        <span class='pykeyword'>return</span> hasattr(module, subclass) <span class='pykeyword'>and</span> getattr(module, subclass) <span class='pykeyword'>or</span> FileInfo
    <span class='pykeyword'>return</span> [getFileInfoClass(f)(f) <span class='pykeyword'>for</span> f <span class='pykeyword'>in</span> fileList]                             
<span class='pykeyword'>if</span> __name__ == <span class='pystring'>"__main__"</span>:
    <span class='pykeyword'>for</span> info <span class='pykeyword'>in</span> listDirectory(<span class='pystring'>"/music/_singles/"</span>, [<span class='pystring'>".mp3"</span>]): <a name="fileinfo_divein.1.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
        <span class='pykeyword'>print</span> <span class='pystring'>"\n"</span>.join([<span class='pystring'>"%s=%s"</span> % (k, v) <span class='pykeyword'>for</span> k, v <span class='pykeyword'>in</span> info.items()])
        print</pre><div class="calloutlist">
                  <table border="0" summary="Callout list">
                     <tr>
                        <td width="12" valign="top" align="left"><a href="#fileinfo_divein.1.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                        </td>
                        <td valign="top" align="left">This program's output depends on the files on your hard drive.  To get meaningful output, you'll need to change the directory
                           path to point to a directory of MP3 files on your own machine.
                        </td>
                     </tr>
                  </table>
               </div>
            </div>
            <div class="informalexample">
               <p>This is the output I got on my machine.  Your output will be different, unless, by some startling coincidence, you share my
                  exact taste in music.
               </p><pre class="screen"><span class="computeroutput">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</span></pre></div>
         </div>
      </div>
      <table class="Footer" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td width="35%" align="left"><br><a class="NavigationArrow" href="../power_of_introspection/summary.html"><< Summary</a></td>
            <td width="30%" align="center"><br> <span class="divider">|</span> <span class="thispage">1</span> <span class="divider">|</span> <a href="importing_modules.html" title="5.2. Importing Modules Using from module import">2</a> <span class="divider">|</span> <a href="defining_classes.html" title="5.3. Defining Classes">3</a> <span class="divider">|</span> <a href="instantiating_classes.html" title="5.4. Instantiating Classes">4</a> <span class="divider">|</span> <a href="userdict.html" title="5.5. Exploring UserDict: A Wrapper Class">5</a> <span class="divider">|</span> <a href="special_class_methods.html" title="5.6. Special Class Methods">6</a> <span class="divider">|</span> <a href="special_class_methods2.html" title="5.7. Advanced Special Class Methods">7</a> <span class="divider">|</span> <a href="class_attributes.html" title="5.8. Introducing Class Attributes">8</a> <span class="divider">|</span> <a href="private_functions.html" title="5.9. Private Functions">9</a> <span class="divider">|</span> <a href="summary.html" title="5.10. Summary">10</a> <span class="divider">|</span> 
            </td>
            <td width="35%" align="right"><br><a class="NavigationArrow" href="importing_modules.html">Importing Modules Using from module import >></a></td>
         </tr>
         <tr>
            <td colspan="3"><br></td>
         </tr>
      </table>
      <div class="Footer">
         <p class="copyright">Copyright © 2000, 2001, 2002, 2003, 2004 <a href="mailto:mark@diveintopython.org">Mark Pilgrim</a></p>
      </div>
   </body>
</html> 
     |