4

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:

  • holygrail/
    • __init__.py
    • knights.py

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()?

1
  • 1
    put import knights in your init.py Commented Jul 16, 2014 at 19:53

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

1 Comment

This is a bad idea seeing as it says in the Python Zen that explicit is better than implicit. Above is definitely a case of implicit; the user of the package may not want this to happen, it would only 'help' (saving like 10 characters at the expense of making the code harder to read) in this specific case.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.