简体   繁体   中英

How do I access a module from a package using Python's zipimport?

I wrote a simple Python package using python's paster, where my package has the directory structure:

pkg/
    __init__.py
    module1.py
    subpackage/
        __init__.py
        module2.py

The init .py files are blank and module1.py contains a function that imports something from module2.py. I install the package and I'm able to call functions in module1.py from the python prompt:

import pkg.module1

I go to where the package was installed (/usr/lib/python2.7/dist-packages/pkg/) and zip the pkg directory:

zip -r pkg.zip pkg/

I try to access the module from the python prompt using zipimport:

import zipimport
importer = zipimport.zipimporter('pkg.zip')
importer.find_module('pkg')
# <zipimporter object "pkg.zip">
importer.load_module('pkg')
# <module 'pkg' from 'pkg.zip/pkg/__init__.pyc'>
importer.is_package('pkg')
# True
pkg = importer.load_module('pkg')
# trying to call a function in module 1 called fcn1
pkg.module1.fcn1()
#Traceback (most recent call last):
#File "<stdin>", line 1, in <module>
#AttributeError: 'module' object has no attribute 'module1'
pkg.module1
#Traceback (most recent call last):
#File "<stdin>", line 1, in <module>
#AttributeError: 'module' object has no attribute 'module1'

Any ideas on how to access module1? Thanks.

Try the following:

import sys
sys.path.append('./pkg.zip') # Or path to pkg.zip
import module1

module1.fcn1()

This will use zipimport for you.

I think that you may need to list the public parts of your module in it's init .py file take a look at PEP 273

When I looked at other established packages like bs4, their __init__.py files had code that allowed you to access other modules. For example, the class BeautifulSoup is in the __init__.py file. If someone knows how to access modules without changing the original code, that would be great. Otherwise, changing __init__.py works.

You are missing a step. If your package was not in a zip file, you would do:

import pkg
import pkg.module1   # You did not do this.
result = pkg.module1.fnc1()

OR file contents of pkg\\__init__.py could instead be:

import module1 # __init__.py does it for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM