Question

I asked a similar question yesterday, but have acquired a really odd problem since then. With this directory structure:

app/
    models/
        __init__.py
        user.py
        other.py
    pages/
        __init__.py
        pages.py

The models/__init__.py file has this line:

__all__ = ['user', 'other']

and the pages/__init__.py has

__all__ = ['pages']

In pages.py, in order to use any of the classes in user.py or other.py, I have to have

from models import *
import models

at the top, and then I can declare a User class like this:

my_user = models.user.User()

If I exclude either of the import-ing statements at the top, I get errors like

"Class user has no attribute User"

Any help would be appreciated. I love Python, but I wish it's import functionality worked more like PHP's.

Was it helpful?

Solution

There are two options, depending on where you want to be explicit and how much you want available "by default" (which also means forced).

In those __init__ files you could use:

# models/__init__.py shown:
import user, other                 # ambiguous relative import
from . import user, other          # relative import
from app.models import user, other # absolute import

Or, where you would otherwise just have import models, use:

from models import user, other
# or:
import models.user, models.other

The latter form is more widely preferred.

OTHER TIPS

One thing that can be real helpful when you're learning python (or debugging), is to run interactively and use the dir() function to see what lives where:

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> import models
>>> dir(models)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
>>> models.user
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'user'
>>> from models import *
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'models', 'other', 'user']
>>> dir(models)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__','__path__', 'other', 'user']
>>> user
<module 'models.user' from 'C:\test\models\user.py'>
>>> models.user
<module 'models.user' from 'C:\test\models\user.py'>
>>> user.User
<class 'models.user.User'>

Update: fixed output.

import models.user
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top