Can't get Python to import from a different folder

I can't seem to get Python to import a module in a subfolder. I get the error when I try to create an instance of the class from the imported module, but the import itself succeeds. Here is my directory structure:

Server
    -server.py
    -Models
        --user.py

Here's the contents of server.py:

from sys import path
from os import getcwd
path.append(getcwd() + "\\models") #Yes, i'm on windows
print path
import user

u=user.User() #error on this line

And user.py:

class User(Entity):
    using_options(tablename='users')

    username = Field(String(15))
    password = Field(String(64))
    email    = Field(String(50))
    status   = Field(Integer)
    created  = Field(DateTime)

The error is: AttributeError: 'module' object has no attribute 'User'


Solution 1:

I believe you need to create a file called __init__.py in the Models directory so that python treats it as a module.

Then you can do:

from Models.user import User

You can include code in the __init__.py (for instance initialization code that a few different classes need) or leave it blank. But it must be there.

Solution 2:

You have to create __init__.py on the Models subfolder. The file may be empty. It defines a package.

Then you can do:

from Models.user import User

Read all about it in python tutorial, here.

There is also a good article about file organization of python projects here.

Solution 3:

import user

u=user.User() #error on this line

Because of the lack of __init__ mentioned above, you would expect an ImportError which would make the problem clearer.

You don't get one because 'user' is also an existing module in the standard library. Your import statement grabs that one and tries to find the User class inside it; that doesn't exist and only then do you get the error.

It is generally a good idea to make your import absolute:

import Server.Models.user

to avoid this kind of ambiguity. Indeed from Python 2.7 'import user' won't look relative to the current module at all.

If you really want relative imports, you can have them explicitly in Python 2.5 and up using the somewhat ugly syntax:

from .user import User