<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>zipimport – Load Python code from inside ZIP archives — Python Module of the Week</title> <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '1.132', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="author" title="About these documents" href="../about.html" /> <link rel="top" title="Python Module of the Week" href="../index.html" /> <link rel="up" title="Importing Modules" href="../importing.html" /> <link rel="next" title="Miscelaneous" href="../miscelaneous.html" /> <link rel="prev" title="pkgutil – Package Utilities" href="../pkgutil/index.html" /> </head> <body> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li class="right" > <a href="../miscelaneous.html" title="Miscelaneous" accesskey="N">next</a> |</li> <li class="right" > <a href="../pkgutil/index.html" title="pkgutil – Package Utilities" accesskey="P">previous</a> |</li> <li><a href="../contents.html">PyMOTW</a> »</li> <li><a href="../importing.html" accesskey="U">Importing Modules</a> »</li> </ul> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../contents.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">zipimport – Load Python code from inside ZIP archives</a><ul> <li><a class="reference internal" href="#example">Example</a></li> <li><a class="reference internal" href="#finding-a-module">Finding a Module</a></li> <li><a class="reference internal" href="#accessing-code">Accessing Code</a></li> <li><a class="reference internal" href="#source">Source</a></li> <li><a class="reference internal" href="#packages">Packages</a></li> <li><a class="reference internal" href="#data">Data</a></li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="../pkgutil/index.html" title="previous chapter">pkgutil – Package Utilities</a></p> <h4>Next topic</h4> <p class="topless"><a href="../miscelaneous.html" title="next chapter">Miscelaneous</a></p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../_sources/zipimport/index.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../search.html" method="get"> <input type="text" name="q" size="18" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="module-zipimport"> <span id="zipimport-load-python-code-from-inside-zip-archives"></span><span id="zipimport-ref"></span><h1>zipimport – Load Python code from inside ZIP archives<a class="headerlink" href="#module-zipimport" title="Permalink to this headline">¶</a></h1> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Purpose:</th><td class="field-body">Load Python code from inside ZIP archives.</td> </tr> <tr class="field"><th class="field-name">Python Version:</th><td class="field-body">2.3 and later</td> </tr> </tbody> </table> <p>The <a class="reference internal" href="#module-zipimport" title="zipimport: Load Python code from inside ZIP archives."><tt class="xref py py-mod docutils literal"><span class="pre">zipimport</span></tt></a> module implements the <tt class="xref py py-class docutils literal"><span class="pre">zipimporter</span></tt> class, which can be used to find and load Python modules inside ZIP archives. The <tt class="xref py py-class docutils literal"><span class="pre">zipimporter</span></tt> supports the “import hooks” API specified in <span class="target" id="index-0"></span><a class="pep reference external" href="http://www.python.org/dev/peps/pep-0302"><strong>PEP 302</strong></a>; this is how Python Eggs work.</p> <p>You probably won’t need to use the <a class="reference internal" href="#module-zipimport" title="zipimport: Load Python code from inside ZIP archives."><tt class="xref py py-mod docutils literal"><span class="pre">zipimport</span></tt></a> module directly, since it is possible to import directly from a ZIP archive as long as that archive appears in your <a class="reference internal" href="../sys/imports.html#sys-path"><em>sys.path</em></a>. However, it is interesting to see the features available.</p> <div class="section" id="example"> <h2>Example<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h2> <p>For the examples this week, I’ll reuse some of the code from last week’s discussion of zipfile to create an example ZIP archive containing some Python modules. If you are experimenting with the sample code on your system, run <tt class="docutils literal"><span class="pre">zipimport_make_example.py</span></tt> before any of the rest of the examples. It will create a ZIP archive containing all of the modules in the example directory, along with some test data needed for the code below.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">zipfile</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span> <span class="n">zf</span> <span class="o">=</span> <span class="n">zipfile</span><span class="o">.</span><span class="n">PyZipFile</span><span class="p">(</span><span class="s">'zipimport_example.zip'</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s">'w'</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">zf</span><span class="o">.</span><span class="n">writepy</span><span class="p">(</span><span class="s">'.'</span><span class="p">)</span> <span class="n">zf</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'zipimport_get_source.py'</span><span class="p">)</span> <span class="n">zf</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'example_package/README.txt'</span><span class="p">)</span> <span class="k">finally</span><span class="p">:</span> <span class="n">zf</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">zf</span><span class="o">.</span><span class="n">namelist</span><span class="p">():</span> <span class="k">print</span> <span class="n">name</span> </pre></div> </div> <div class="highlight-python"><pre>$ python zipimport_make_example.py __init__.pyc example_package/__init__.pyc zipimport_find_module.pyc zipimport_get_code.pyc zipimport_get_data.pyc zipimport_get_data_nozip.pyc zipimport_get_data_zip.pyc zipimport_get_source.pyc zipimport_is_package.pyc zipimport_load_module.pyc zipimport_make_example.pyc zipimport_get_source.py example_package/README.txt</pre> </div> </div> <div class="section" id="finding-a-module"> <h2>Finding a Module<a class="headerlink" href="#finding-a-module" title="Permalink to this headline">¶</a></h2> <p>Given the full name of a module, <tt class="xref py py-func docutils literal"><span class="pre">find_module()</span></tt> will try to locate that module inside the ZIP archive.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">zipimport</span> <span class="n">importer</span> <span class="o">=</span> <span class="n">zipimport</span><span class="o">.</span><span class="n">zipimporter</span><span class="p">(</span><span class="s">'zipimport_example.zip'</span><span class="p">)</span> <span class="k">for</span> <span class="n">module_name</span> <span class="ow">in</span> <span class="p">[</span> <span class="s">'zipimport_find_module'</span><span class="p">,</span> <span class="s">'not_there'</span> <span class="p">]:</span> <span class="k">print</span> <span class="n">module_name</span><span class="p">,</span> <span class="s">':'</span><span class="p">,</span> <span class="n">importer</span><span class="o">.</span><span class="n">find_module</span><span class="p">(</span><span class="n">module_name</span><span class="p">)</span> </pre></div> </div> <p>If the module is found, the <tt class="xref py py-class docutils literal"><span class="pre">zipimporter</span></tt> instance is returned. Otherwise, <tt class="xref docutils literal"><span class="pre">None</span></tt> is returned.</p> <div class="highlight-python"><pre>$ python zipimport_find_module.py zipimport_find_module : <zipimporter object "zipimport_example.zip"> not_there : None</pre> </div> </div> <div class="section" id="accessing-code"> <h2>Accessing Code<a class="headerlink" href="#accessing-code" title="Permalink to this headline">¶</a></h2> <p>The <tt class="xref py py-func docutils literal"><span class="pre">get_code()</span></tt> method loads the code object for a module from the archive.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">zipimport</span> <span class="n">importer</span> <span class="o">=</span> <span class="n">zipimport</span><span class="o">.</span><span class="n">zipimporter</span><span class="p">(</span><span class="s">'zipimport_example.zip'</span><span class="p">)</span> <span class="n">code</span> <span class="o">=</span> <span class="n">importer</span><span class="o">.</span><span class="n">get_code</span><span class="p">(</span><span class="s">'zipimport_get_code'</span><span class="p">)</span> <span class="k">print</span> <span class="n">code</span> </pre></div> </div> <p>The code object is not the same as a module object.</p> <div class="highlight-python"><pre>$ python zipimport_get_code.py <code object <module> at 0x1002b73b0, file "./zipimport_get_code.py", line 7></pre> </div> <p>To load the code as a usable module, use <tt class="xref py py-func docutils literal"><span class="pre">load_module()</span></tt> instead.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">zipimport</span> <span class="n">importer</span> <span class="o">=</span> <span class="n">zipimport</span><span class="o">.</span><span class="n">zipimporter</span><span class="p">(</span><span class="s">'zipimport_example.zip'</span><span class="p">)</span> <span class="n">module</span> <span class="o">=</span> <span class="n">importer</span><span class="o">.</span><span class="n">load_module</span><span class="p">(</span><span class="s">'zipimport_get_code'</span><span class="p">)</span> <span class="k">print</span> <span class="s">'Name :'</span><span class="p">,</span> <span class="n">module</span><span class="o">.</span><span class="n">__name__</span> <span class="k">print</span> <span class="s">'Loader :'</span><span class="p">,</span> <span class="n">module</span><span class="o">.</span><span class="n">__loader__</span> <span class="k">print</span> <span class="s">'Code :'</span><span class="p">,</span> <span class="n">module</span><span class="o">.</span><span class="n">code</span> </pre></div> </div> <p>The result is a module object as though the code had been loaded from a regular import:</p> <div class="highlight-python"><pre>$ python zipimport_load_module.py <code object <module> at 0x100431d30, file "./zipimport_get_code.py", line 7> Name : zipimport_get_code Loader : <zipimporter object "zipimport_example.zip"> Code : <code object <module> at 0x100431d30, file "./zipimport_get_code.py", line 7></pre> </div> </div> <div class="section" id="source"> <h2>Source<a class="headerlink" href="#source" title="Permalink to this headline">¶</a></h2> <p>As with the <a class="reference internal" href="../inspect/index.html#module-inspect" title="inspect: Inspect live objects"><tt class="xref py py-mod docutils literal"><span class="pre">inspect</span></tt></a> module, it is possible to retrieve the source code for a module from the ZIP archive, if the archive includes the source. In the case of the example, only <tt class="docutils literal"><span class="pre">zipimport_get_source.py</span></tt> is added to <tt class="docutils literal"><span class="pre">zipimport_example.zip</span></tt> (the rest of the modules are just added as the .pyc files).</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">zipimport</span> <span class="n">importer</span> <span class="o">=</span> <span class="n">zipimport</span><span class="o">.</span><span class="n">zipimporter</span><span class="p">(</span><span class="s">'zipimport_example.zip'</span><span class="p">)</span> <span class="k">for</span> <span class="n">module_name</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'zipimport_get_code'</span><span class="p">,</span> <span class="s">'zipimport_get_source'</span><span class="p">]:</span> <span class="n">source</span> <span class="o">=</span> <span class="n">importer</span><span class="o">.</span><span class="n">get_source</span><span class="p">(</span><span class="n">module_name</span><span class="p">)</span> <span class="k">print</span> <span class="s">'='</span> <span class="o">*</span> <span class="mi">80</span> <span class="k">print</span> <span class="n">module_name</span> <span class="k">print</span> <span class="s">'='</span> <span class="o">*</span> <span class="mi">80</span> <span class="k">print</span> <span class="n">source</span> <span class="k">print</span> </pre></div> </div> <p>If the source for a module is not available, <tt class="xref py py-func docutils literal"><span class="pre">get_source()</span></tt> returns <tt class="xref docutils literal"><span class="pre">None</span></tt>.</p> <div class="highlight-python"><pre>$ python zipimport_get_source.py ================================================================================ zipimport_get_code ================================================================================ None ================================================================================ zipimport_get_source ================================================================================ #!/usr/bin/env python # # Copyright 2007 Doug Hellmann. # """Retrieving the source code for a module within a zip archive. """ #end_pymotw_header import zipimport importer = zipimport.zipimporter('zipimport_example.zip') for module_name in ['zipimport_get_code', 'zipimport_get_source']: source = importer.get_source(module_name) print '=' * 80 print module_name print '=' * 80 print source print</pre> </div> </div> <div class="section" id="packages"> <h2>Packages<a class="headerlink" href="#packages" title="Permalink to this headline">¶</a></h2> <p>To determine if a name refers to a package instead of a regular module, use <tt class="xref py py-func docutils literal"><span class="pre">is_package()</span></tt>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">zipimport</span> <span class="n">importer</span> <span class="o">=</span> <span class="n">zipimport</span><span class="o">.</span><span class="n">zipimporter</span><span class="p">(</span><span class="s">'zipimport_example.zip'</span><span class="p">)</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'zipimport_is_package'</span><span class="p">,</span> <span class="s">'example_package'</span><span class="p">]:</span> <span class="k">print</span> <span class="n">name</span><span class="p">,</span> <span class="n">importer</span><span class="o">.</span><span class="n">is_package</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> </pre></div> </div> <p>In this case, <tt class="docutils literal"><span class="pre">zipimport_is_package</span></tt> came from a module and the <tt class="docutils literal"><span class="pre">example_package</span></tt> is a package.</p> <div class="highlight-python"><pre>$ python zipimport_is_package.py zipimport_is_package False example_package True</pre> </div> </div> <div class="section" id="data"> <h2>Data<a class="headerlink" href="#data" title="Permalink to this headline">¶</a></h2> <p>There are times when source modules or packages need to be distributed with non-code data. Images, configuration files, default data, and test fixtures are just a few examples of this. Frequently, the module <tt class="docutils literal"><span class="pre">__path__</span></tt> attribute is used to find these data files relative to where the code is installed.</p> <p>For example, with a normal module you might do something like:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">example_package</span> <span class="n">data_filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">example_package</span><span class="o">.</span><span class="n">__file__</span><span class="p">),</span> <span class="s">'README.txt'</span><span class="p">)</span> <span class="k">print</span> <span class="n">data_filename</span><span class="p">,</span> <span class="s">':'</span> <span class="k">print</span> <span class="nb">open</span><span class="p">(</span><span class="n">data_filename</span><span class="p">,</span> <span class="s">'rt'</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> </pre></div> </div> <p>The output will look something like this, with the path changed based on where the PyMOTW sample code is on your filesystem.</p> <div class="highlight-python"><pre>$ python zipimport_get_data_nozip.py /Users/dhellmann/Documents/PyMOTW/src/PyMOTW/zipimport/example_package/README.txt : This file represents sample data which could be embedded in the ZIP archive. You could include a configuration file, images, or any other sort of non-code data.</pre> </div> <p>If the <tt class="docutils literal"><span class="pre">example_package</span></tt> is imported from the ZIP archive instead of the filesystem, that method does not work:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">sys</span> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s">'zipimport_example.zip'</span><span class="p">)</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">example_package</span> <span class="k">print</span> <span class="n">example_package</span><span class="o">.</span><span class="n">__file__</span> <span class="n">data_filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">example_package</span><span class="o">.</span><span class="n">__file__</span><span class="p">),</span> <span class="s">'README.txt'</span><span class="p">)</span> <span class="k">print</span> <span class="n">data_filename</span><span class="p">,</span> <span class="s">':'</span> <span class="k">print</span> <span class="nb">open</span><span class="p">(</span><span class="n">data_filename</span><span class="p">,</span> <span class="s">'rt'</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> </pre></div> </div> <p>The <tt class="docutils literal"><span class="pre">__file__</span></tt> of the package refers to the ZIP archive, and not a directory. So we cannot just build up the path to the <tt class="docutils literal"><span class="pre">README.txt</span></tt> file.</p> <div class="highlight-python"><pre>$ python zipimport_get_data_zip.py zipimport_example.zip/example_package/__init__.pyc zipimport_example.zip/example_package/README.txt : Traceback (most recent call last): File "zipimport_get_data_zip.py", line 40, in <module> print open(data_filename, 'rt').read() IOError: [Errno 20] Not a directory: 'zipimport_example.zip/example_package/README.txt'</pre> </div> <p>Instead, we need to use the <tt class="xref py py-func docutils literal"><span class="pre">get_data()</span></tt> method. We can access <tt class="xref py py-class docutils literal"><span class="pre">zipimporter</span></tt> instance which loaded the module through the <tt class="docutils literal"><span class="pre">__loader__</span></tt> attribute of the imported module:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">sys</span> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s">'zipimport_example.zip'</span><span class="p">)</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">example_package</span> <span class="k">print</span> <span class="n">example_package</span><span class="o">.</span><span class="n">__file__</span> <span class="k">print</span> <span class="n">example_package</span><span class="o">.</span><span class="n">__loader__</span><span class="o">.</span><span class="n">get_data</span><span class="p">(</span><span class="s">'example_package/README.txt'</span><span class="p">)</span> </pre></div> </div> <div class="highlight-python"><pre>$ python zipimport_get_data.py zipimport_example.zip/example_package/__init__.pyc This file represents sample data which could be embedded in the ZIP archive. You could include a configuration file, images, or any other sort of non-code data.</pre> </div> <p>The <tt class="docutils literal"><span class="pre">__loader__</span></tt> is not set for modules not imported via <a class="reference internal" href="#module-zipimport" title="zipimport: Load Python code from inside ZIP archives."><tt class="xref py py-mod docutils literal"><span class="pre">zipimport</span></tt></a>.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <dl class="last docutils"> <dt><a class="reference external" href="http://docs.python.org/lib/module-zipimport.html">zipimport</a></dt> <dd>Standard library documentation for this module.</dd> <dt><a class="reference internal" href="../imp/index.html#module-imp" title="imp: Interface to module import mechanism."><tt class="xref py py-mod docutils literal"><span class="pre">imp</span></tt></a></dt> <dd>Other import-related functions.</dd> <dt><span class="target" id="index-1"></span><a class="pep reference external" href="http://www.python.org/dev/peps/pep-0302"><strong>PEP 302</strong></a></dt> <dd>New Import Hooks</dd> <dt><a class="reference internal" href="../pkgutil/index.html#module-pkgutil" title="pkgutil: Package utilities"><tt class="xref py py-mod docutils literal"><span class="pre">pkgutil</span></tt></a></dt> <dd>Provides a more generic interface to <tt class="xref py py-func docutils literal"><span class="pre">get_data()</span></tt>.</dd> </dl> </div> </div> </div> </div> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li class="right" > <a href="../miscelaneous.html" title="Miscelaneous" >next</a> |</li> <li class="right" > <a href="../pkgutil/index.html" title="pkgutil – Package Utilities" >previous</a> |</li> <li><a href="../contents.html">PyMOTW</a> »</li> <li><a href="../importing.html" >Importing Modules</a> »</li> </ul> </div> <div class="footer"> © Copyright Doug Hellmann. Last updated on Oct 24, 2010. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>. <br/><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/" rel="license"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png"/></a> </div> </body> </html>