parkus
parkus

Reputation: 133

Python doesn't find the modules in my package

I must be missing something very basic about building a package in Python. When I create a package following the guidelines of https://docs.python.org/2/tutorial/modules.html#packages and import it, Python does not find any of the modules. For example, say I create the package holygrail with the following structure:

I leave __init__.py empty because the docs say that I can and I'm just trying to make a basic package to start. In knights.py I have:

def say():
     print 'Ni!'

If I try import holygrail, Python doesn't give any errors, but holygrail.knights.say() results in Python telling me that the "'module' object [holygrail] has no attribute 'knights'." However, if I specifically import knights via from holygrail import knights, then knights.say() works. In addition, holygrail.knights.say() then also works.

I tried adding the line

__all__  = ['knights']

in the __init__.py file, but this did not change the behavior.

How do I construct a package such that import package loads in all of the modules, allowing statements like package.module.function()?

Upvotes: 4

Views: 1534

Answers (2)

famousgarkin
famousgarkin

Reputation: 14116

Python does not implicitly import the whole package hierarchy. You have to be explicit about what to import on what level of the package using the __init__.py files.

When you set __all__ = ['knights'] in the __init__.py it works only for the import all statements for that module, e.g.:

>>> import holygrail
>>> holygrail.knights.say()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'knights'

>>> from holygrail import *
>>> knights.say()
Ni!

It can also act as a filter on import all, importing from the module only what's specified.

To get knights automatically imported on import holygrail you have to put import knights or from . import knights (intra-package or relative import) to the __init__.py. You'll have to do the same for every module explicitly.

Upvotes: 3

user3715319
user3715319

Reputation: 31

Add import knights into __init__.py.

The link you provided does state "In the simplest case, __init__.py can just be an empty file..." Your example is not the simplest case, that's all.

Upvotes: 1

Related Questions