Python3 correct way to import relative or absolute?

Solution 1:

In Python 3, implicit relative imports are forbidden, see https://www.python.org/dev/peps/pep-0328/ and https://docs.python.org/release/3.0.1/whatsnew/3.0.html#removed-syntax:

The only acceptable syntax for relative imports is from .[module] import name. All import forms not starting with . are interpreted as absolute imports. (PEP 0328)

from .stuff import Stuff is an explicit relative import, which you "should" make use of whenever possible, and must use in Python 3, whenever possible. Head over to https://stackoverflow.com/a/12173406/145400 for a deeper analysis on relative imports.

Solution 2:

Relative import usage has changed from python2 to python3,

The only acceptable syntax for relative imports is from .[module] import name. All import forms not starting with . are interpreted as absolute imports. (PEP 0328)

Python’s -m switch allows running a module as a script. When you ran a module that was located inside a package, relative imports didn’t work correctly. The fix for Python 2.6 adds a __package__ attribute to modules. When this attribute is present, relative imports will be relative to the value of this attribute instead of the __name__ attribute. (PEP 0366)

To your questions:

  1. You get SystemError: Parent module '' not loaded, cannot perform relative import or in Python3.5 and forward you would get ImportError: attempted relative import with no known parent package when you run python neuralnet.py and try to import from . import layers as your __package__ would be None and PYTHONPATH will only have current file(and not its parent), hence it can't find layer.

You may either run the module like this:

python -m neuralnet.neuralnet

Here your __package__ will be neuralnet, hence you will be able to import the neuralnet module which is within it.

Or you may do this workaround:

Update the __init__.py in neuralnet package to:

import os
import sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))

Then run your script neuralnet.py, the above lines will add neuralnet directory to the PYTHONPATH.

  1. You get ImportError: No module named 'layer' when layer is not a module that is in your PYTHONPATH so either install it or add it to the PATH using

    import sys
    sys.path.append("/path/to/layer")
    

Background:

Part of a message from Guido(author of Python):

... in 2.4, we introduce the leading dot notation for relative import, while still allowing relative import without a leading dot. In 2.5 we can start warning about relative import without a leading dot (although that will undoubtedly get complaints from folks who have code that needs to work with 2.3 still). In 3.0 we can retire ambiguous import.

The use case for multiple dots should be obvious: inside a highly structured package, modules inside one subpackage must have a way to do relative import from another subpackage of the same parent package.

There is the remaining issue of what exactly the syntax would be. I propose to extend the from clause to allow one or more dots before the dotted name, and to make the dotted name optional if at least one leading dot is found. I propose not to change from-less import.

Examples:

  from .foo import bar
  from .foo.bar import xxx
  from . import foobar as barfoo
  from ..foo.bar import *
  from ... import foobar, barfoo

Relavent PEP to read: PEP-328