If you've run into trouble with imports while converting Python 2 to Python 3, there's 3 main differences to keep in mind:
Suppose you have the following files:
|~/myProject/start.py||I'm the entry point of execution and I import stuff.foo.|
|~/myProject/stuff/foo.py||I import the file bar.py.|
|~/myProject/stuff/bar.py||I provide useful goods and services. I am a bar, afterall.|
|~/myProject/stuff/__init__.py||I'm empty and irrelevant to this example.|
In Python 2, you can simply invoke import bar in foo.py because they are in the same directory, regardless of whether you began execution of your script in main.py. However, in Python 3, you must use the whole path such as import stuff.foo OR specify that the import occurs from the current file's directory using a . e.g. from . import foo.
Python 3 doesn't allow you to use import inside functions. You can still import from inside other constructs placed in the top-level scope, though, such as if statements.
In Python 3, you can omit __init__.py in a directory. In Python 2, it is required, even if blank. Although since you're probably converting Python 2 code to Python 3 code while reading this, this is unlikely to be causing you trouble.
Is your import still not working? Here's a crash course refresher of how imports work in general (for both Python 2 and 3):
Python has a list of directories where it searches. This list can be seen (and even modified) from sys.path. Where does this list initially come from? Well, it's complicated. But basically it's a combination of the PYTHONPATH environment variable, some directories in the Python installation, and some directories the Python installation thinks might be good places to look. The first item is generally the location of where the entry point of your script is running.
At the time of import, it will loop through this list and check each of those directories for the following:
- A .py file with that name
- A directory with that name (and if you're using Python 2, this directory must also contain an __init__.py).
And that's really all it's doing. Of course, all this only applies to the first step of the import, e.g. how Python finds the myPackage of import myPackage.subPackage.