I want to import a function from another file in the same directory.
Usually, one of the following works:
from .mymodule import myfunction
from mymodule import myfunction
…but the other one gives me one of these errors:
ImportError: attempted relative import with no known parent package
ModuleNotFoundError: No module named 'mymodule'
SystemError: Parent module '' not loaded, cannot perform relative import
Why is this?
Best Answer
It's quite common to have a layout like this...
...with a
mymodule.py
like this......a
myothermodule.py
like this......and a
main.py
like this......which works fine when you run
main.py
ormypackage/mymodule.py
, but fails withmypackage/myothermodule.py
, due to the relative import...The way you're supposed to run it is by using the -m option and giving the path in the Python module system (rather than in the filesystem)...
...but it's somewhat verbose, and doesn't mix well with a shebang line like
#!/usr/bin/env python3
.An alternative is to avoid using relative imports, and just use...
Either way, you'll need to run from the parent of
mypackage
, or add that directory toPYTHONPATH
(either one will ensure thatmypackage
is in the sys.path module search path). Or, if you want it to work "out of the box", you can frob thePYTHONPATH
in code first with this...It's kind of a pain, but there's a clue as to why in an email written by a certain Guido van Rossum...
Whether running scripts inside a package is an antipattern or not is subjective, but personally I find it really useful in a package I have which contains some custom wxPython widgets, so I can run the script for any of the source files to display a
wx.Frame
containing only that widget for testing purposes.