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:
- You get
SystemError: Parent module '' not loaded, cannot perform relative import
or in Python3.5 and forward you would getImportError: attempted relative import with no known parent package
when you runpython neuralnet.py
and try to importfrom . import layers
as your__package__
would beNone
and PYTHONPATH will only have current file(and not its parent), hence it can't findlayer
.
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.
-
You get
ImportError: No module named 'layer'
whenlayer
is not a module that is in your PYTHONPATH so either install it or add it to the PATH usingimport 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