I have a directory structure with 2 basic python files inside seperate directories:
├── package
│ ├── subpackage1
│ │ └── module1.py
└── subpackage2
└── module2.py
module1.py:
def module1():
print('hello world')
module2.py:
from ..subpackage1.module1 import module1
module1()
When running python3 module2.py
I get the error: ImportError: attempted relative import with no known parent package
However when I run it with the imports changed to use sys.path.append()
it runs successfully
import sys
sys.path.append('../subpackage1/')
from module1 import module1
module1()
Can anyone help me understand why this is and how to correct my code so that I can do this with relative imports?
CodePudding user response:
To be considered a package, a Python directory has to include an __init__.py
file. Since your module2.py
file is not below a directory that contains an __init__.py
file, it isn't considered to be part of a package. Relative imports only work inside packages.
CodePudding user response:
By default, Python just considers a directory with code in it to be a directory with code in it, not a package/subpackage. In order to make it into a package, you'll need to add an __init__.py
file to each one, as well as an __init__.py
file to within the main package
directory.
CodePudding user response:
Even adding the __init__.py
files won't be enough, but you should. You should also create a setup.py
file next to your package
directory. Your file tree would look like this:
├── setup.py
└── package
├── __init__.py
└── subpackage1
│ ├── __init__.py
│ └── module1.py
└── subpackage2
├── __init__.py
└── module2.py
This setup.py
file could start off like this:
from setuptools import setup
setup(
name='package',
packages=['package'],
)
These configurations are enough to get you started. Then, on the root of your directory (parent folder to package
and setup.py
), you will execute next command in you terminal pip install -e .
to install your package, named package, in development mode. Then you'll be able to navigate to package/subpackage2/ and execute python module2.py
having your expected result. You could even execute python package/subpackage2/module2.py
and it works.
The thing is, modules and packages don't work the same way they work in another programming languages. Without the creation of setup.py
if you were to create a program in your root directory, named main.py
for example, then you could import modules from inside package folder tree. But if you're looking to execute package\subpackage2\module2.py.