File: packages.html

package info (click to toggle)
diveintopython 5.4-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, jessie, jessie-kfreebsd, lenny, squeeze, wheezy
  • size: 4,116 kB
  • ctags: 2,838
  • sloc: python: 4,417; xml: 894; makefile: 29
file content (165 lines) | stat: -rw-r--r-- 16,449 bytes parent folder | download | duplicates (2)
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

<!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>9.2.&nbsp;Packages</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="index.html" title="Chapter&nbsp;9.&nbsp;XML Processing">
      <link rel="previous" href="index.html" title="Chapter&nbsp;9.&nbsp;XML Processing">
      <link rel="next" href="parsing_xml.html" title="9.3.&nbsp;Parsing XML">
   </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>&nbsp;&gt;&nbsp;<a href="../toc/index.html">Dive Into Python</a>&nbsp;&gt;&nbsp;<a href="index.html">XML Processing</a>&nbsp;&gt;&nbsp;<span class="thispage">Packages</span></td>
            <td id="navigation" align="right" valign="top">&nbsp;&nbsp;&nbsp;<a href="index.html" title="Prev: &#8220;XML Processing&#8221;">&lt;&lt;</a>&nbsp;&nbsp;&nbsp;<a href="parsing_xml.html" title="Next: &#8220;Parsing XML&#8221;">&gt;&gt;</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:&nbsp;</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="section" lang="en">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title"><a name="kgp.packages"></a>9.2.&nbsp;Packages
                  </h2>
               </div>
            </div>
            <div></div>
         </div>
         <div class="abstract">
            <p>Actually parsing an <span class="acronym">XML</span> document is very simple: one line of code.  However, before you get to that line of code, you need to take a short detour
               to talk about packages.
            </p>
         </div>
         <div class="example"><a name="d0e22925"></a><h3 class="title">Example&nbsp;9.5.&nbsp;Loading an <span class="acronym">XML</span> document (a sneak peek)
            </h3><pre class="screen">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput"><span class='pykeyword'>from</span> xml.dom <span class='pykeyword'>import</span> minidom</span> <a name="kgp.packages.1.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">xmldoc = minidom.parse(<span class='pystring'>'~/diveintopython/common/py/kgp/binary.xml'</span>)</span></pre><div class="calloutlist">
               <table border="0" summary="Callout list">
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#kgp.packages.1.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">This is a syntax you haven't seen before.  It looks almost like the <tt class="literal">from <i class="replaceable">module</i> import</tt> you know and love, but the <tt class="literal">"."</tt> gives it away as something above and beyond a simple import.  In fact, <tt class="filename">xml</tt> is what is known as a package, <tt class="filename">dom</tt> is a nested package within <tt class="filename">xml</tt>, and <tt class="filename">minidom</tt> is a module within <tt class="filename">xml.dom</tt>.
                     </td>
                  </tr>
               </table>
            </div>
         </div>
         <p>That sounds complicated, but it's really not.  Looking at the actual implementation may help.  Packages are little more than
            directories of modules; nested packages are subdirectories.  The modules within a package (or a nested package) are still
            just <tt class="filename">.py</tt> files, like always, except that they're in a subdirectory instead of the main <tt class="filename">lib/</tt> directory of your <span class="application">Python</span> installation.
         </p>
         <div class="example"><a name="d0e22983"></a><h3 class="title">Example&nbsp;9.6.&nbsp;File layout of a package</h3><pre class="screen"><span class="computeroutput"><span class="application">Python</span>21/           root <span class="application">Python</span> installation (home of the executable)
|
+--lib/             library directory (home of the standard library modules)
   |
   +-- xml/         xml package (really just a directory with other stuff in it)
       |
       +--sax/      xml.sax package (again, just a directory)
       |
       +--dom/      xml.dom package (contains minidom.py)
       |
       +--parsers/  xml.parsers package (used internally)</span></pre></div>
         <p>So when you say <tt class="literal">from xml.dom import minidom</tt>, <span class="application">Python</span> figures out that that means &#8220;<span class="quote">look in the <tt class="filename">xml</tt> directory for a <tt class="filename">dom</tt> directory, and look in <span class="emphasis"><em>that</em></span> for the <tt class="filename">minidom</tt> module, and import it as <tt class="filename">minidom</tt></span>&#8221;.  But <span class="application">Python</span> is even smarter than that; not only can you import entire modules contained within a package, you can selectively import
            specific classes or functions from a module contained within a package.  You can also import the package itself as a module.
             The syntax is all the same; <span class="application">Python</span> figures out what you mean based on the file layout of the package, and automatically does the right thing.
         </p>
         <div class="example"><a name="d0e23025"></a><h3 class="title">Example&nbsp;9.7.&nbsp;Packages are modules, too</h3><pre class="screen"><tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput"><span class='pykeyword'>from</span> xml.dom <span class='pykeyword'>import</span> minidom</span>         <a name="kgp.packages.2.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">minidom</span>
<span class="computeroutput">&lt;module 'xml.dom.minidom' from 'C:\Python21\lib\xml\dom\minidom.pyc'&gt;</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">minidom.Element</span>
<span class="computeroutput">&lt;class xml.dom.minidom.Element at 01095744&gt;</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput"><span class='pykeyword'>from</span> xml.dom.minidom <span class='pykeyword'>import</span> Element</span> <a name="kgp.packages.2.2"></a><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">Element</span>
<span class="computeroutput">&lt;class xml.dom.minidom.Element at 01095744&gt;</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">minidom.Element</span>
<span class="computeroutput">&lt;class xml.dom.minidom.Element at 01095744&gt;</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput"><span class='pykeyword'>from</span> xml <span class='pykeyword'>import</span> dom</span>                 <a name="kgp.packages.2.3"></a><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">dom</span>
<span class="computeroutput">&lt;module 'xml.dom' from 'C:\Python21\lib\xml\dom\__init__.pyc'&gt;</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput"><span class='pykeyword'>import</span> xml</span>                          <a name="kgp.packages.2.4"></a><img src="../images/callouts/4.png" alt="4" border="0" width="12" height="12">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">xml</span>
<span class="computeroutput">&lt;module 'xml' from 'C:\Python21\lib\xml\__init__.pyc'&gt;</span></pre><div class="calloutlist">
               <table border="0" summary="Callout list">
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#kgp.packages.2.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">Here you're importing a module (<tt class="filename">minidom</tt>) from a nested package (<tt class="filename">xml.dom</tt>).  The result is that <tt class="filename">minidom</tt> is imported into your <a href="../html_processing/locals_and_globals.html" title="8.5.&nbsp;locals and globals">namespace</a>, and in order to reference classes within the <tt class="filename">minidom</tt> module (like <tt class="classname">Element</tt>), you need to preface them with the module name.
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#kgp.packages.2.2"><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">Here you are importing a class (<tt class="classname">Element</tt>) from a module (<tt class="filename">minidom</tt>) from a nested package (<tt class="filename">xml.dom</tt>).  The result is that <tt class="classname">Element</tt> is imported directly into your namespace.  Note that this does not interfere with the previous import; the <tt class="classname">Element</tt> class can now be referenced in two ways (but it's all still the same class).
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#kgp.packages.2.3"><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">Here you are importing the <tt class="filename">dom</tt> package (a nested package of <tt class="filename">xml</tt>) as a module in and of itself.  Any level of a package can be treated as a module, as you'll see in a moment.  It can even
                        have its own attributes and methods, just the modules you've seen before.
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#kgp.packages.2.4"><img src="../images/callouts/4.png" alt="4" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">Here you are importing the root level <tt class="filename">xml</tt> package as a module.
                     </td>
                  </tr>
               </table>
            </div>
         </div>
         <p>So how can a package (which is just a directory on disk) be imported and treated as a module (which is always a file on disk)?
             The answer is the magical <tt class="filename">__init__.py</tt> file.  You see, packages are not simply directories; they are directories with a specific file, <tt class="filename">__init__.py</tt>, inside.  This file defines the attributes and methods of the package.  For instance, <tt class="filename">xml.dom</tt> contains a <tt class="classname">Node</tt> class, which is defined in <tt class="filename">xml/dom/__init__.py</tt>.  When you import a package as a module (like <tt class="filename">dom</tt> from <tt class="filename">xml</tt>), you're really importing its <tt class="filename">__init__.py</tt> file.
         </p><a name="d0e23185"></a><table class="note" border="0" summary="">
            <tr>
               <td rowspan="2" align="center" valign="top" width="1%"><img src="../images/note.png" alt="Note" title="" width="24" height="24"></td>
            </tr>
            <tr>
               <td colspan="2" align="left" valign="top" width="99%">A package is a directory with the special <tt class="filename">__init__.py</tt> file in it.  The <tt class="filename">__init__.py</tt> file defines the attributes and methods of the package.  It doesn't need to define anything; it can just be an empty file,
                  but it has to exist.  But if <tt class="filename">__init__.py</tt> doesn't exist, the directory is just a directory, not a package, and it can't be imported or contain modules or nested packages.
               </td>
            </tr>
         </table>
         <p>So why bother with packages?  Well, they provide a way to logically group related modules.  Instead of having an <tt class="filename">xml</tt> package with <tt class="filename">sax</tt> and <tt class="filename">dom</tt> packages inside, the authors could have chosen to put all the <tt class="filename">sax</tt> functionality in <tt class="filename">xmlsax.py</tt> and all the <tt class="filename">dom</tt> functionality in <tt class="filename">xmldom.py</tt>, or even put all of it in a single module.  But that would have been unwieldy (as of this writing, the <span class="acronym">XML</span> package has over 3000 lines of code) and difficult to manage (separate source files mean multiple people can work on different
            areas simultaneously).
         </p>
         <p>If you ever find yourself writing a large subsystem in <span class="application">Python</span> (or, more likely, when you realize that your small subsystem has grown into a large one), invest some time designing a good
            package architecture.  It's one of the many things <span class="application">Python</span> is good at, so take advantage of it.
         </p>
      </div>
      <table class="Footer" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td width="35%" align="left"><br><a class="NavigationArrow" href="index.html">&lt;&lt;&nbsp;XML Processing</a></td>
            <td width="30%" align="center"><br>&nbsp;<span class="divider">|</span>&nbsp;<a href="index.html#kgp.divein" title="9.1.&nbsp;Diving in">1</a> <span class="divider">|</span> <span class="thispage">2</span> <span class="divider">|</span> <a href="parsing_xml.html" title="9.3.&nbsp;Parsing XML">3</a> <span class="divider">|</span> <a href="unicode.html" title="9.4.&nbsp;Unicode">4</a> <span class="divider">|</span> <a href="searching.html" title="9.5.&nbsp;Searching for elements">5</a> <span class="divider">|</span> <a href="attributes.html" title="9.6.&nbsp;Accessing element attributes">6</a> <span class="divider">|</span> <a href="summary.html" title="9.7.&nbsp;Segue">7</a>&nbsp;<span class="divider">|</span>&nbsp;
            </td>
            <td width="35%" align="right"><br><a class="NavigationArrow" href="parsing_xml.html">Parsing XML&nbsp;&gt;&gt;</a></td>
         </tr>
         <tr>
            <td colspan="3"><br></td>
         </tr>
      </table>
      <div class="Footer">
         <p class="copyright">Copyright &copy; 2000, 2001, 2002, 2003, 2004 <a href="mailto:mark@diveintopython.org">Mark Pilgrim</a></p>
      </div>
   </body>
</html>