Issue
Thats quite basic but still I am a bit puzzled. I have this toy example where I try to import a function from my_module.py
which looks like:
## my_module.py
def say_hi():
print('Hi!')
See attached pic for my project tree
The import statement from .my_module import say_hi
gives the ImportError: attempted relative import with no known parent package
. However it works fine as from my_module import say_hi
.
I thought these statements were equivalent, especially given the presence of __init__.py
. PyCharm too seems to be happy in both cases, ie a mouse-hover and ctrl key combination over the word my_module, highlights the word.
Solution
Relative imports are not PATH relative, they are PACKAGE relative. They only work within a module that is part of a package when imported by a script outside of the package.
A module is considered to be in a package if it's __name__
at the time of execution contains a .
(example: import my_package.utilities
). The value of __name__
is set to the filename preceded by any packages and subpackage directory names.
So, as an example, if a script outside of your my_proj
directory included
import my_proj
, then the two .py files inside would have __name__
set to 'my_proj.main'
and 'my_proj.my_module'
respectively when they are imported as members of the package.
When you execute any script as the top-level script, for example via python script.py
, it's __name__
value is set to '__main__'
, meaning it is not considered to be part of a package by the import system, even if its in a directory with the file you're trying to import from. Therefore, the top-level script MUST use absolute imports only.
If you need main.py
in your given structure to function both as a top-level script and also if its imported as part of the package and executed as a module, then you can use try/except to attempt a relative import first, then fall back to an absolute import.
# main.py
try:
from .my_module import say_hi
except ImportError:
from my_module import say_hi
if __name__ == '__main__':
say_hi()
I consider this answer to be the definitive explanation of relative imports in Python on Stack Overflow, and it's where I learned most of this (and cross-referenced while writing this answer)
See also this similar post I answered a few days before this one: Import from another file inside the same module and running from a main.py outside the module throws an import error
Answered By - nigh_anxiety
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.