Reputation: 15578
I have a directory structure like this.
Chatbot/
utils/
abc.py
projects/
proj1/
utils/
__init__.py
data_process.py
components/
class1.py
I have two utils
folders in my structure, one at the top level and one inside my projects folder.
Now I want to import data_process.py
file inside class1.py
. So I tried like this
from utils.data_process import DataProcess
but it is referencing the top-level utils
folder and even VSCode is not recognizing it. I tried creating __init__.py
file inside the utils
folder but still did not work.
I tried with empty __init__.py
and then placing this content
from . import data_process
__all__ = ['data_proces']
then
from .data_process import DataPreprocess
__all__ = ['DataPreprocess']
then I tried
from ..utils.data_process import DataProcess
VSCode is recognizing this but it is not working and throws the error
ValueError: attempted relative import beyond top-level package
Even I tried changing the name utils to some other name but still the same issue
How can I solve this?
Upvotes: 2
Views: 12022
Reputation: 552
A python module is defined by a special file called __init__.py
and this file should be present in all the subdirectories. So, your file structure would be:
Chatbot/
__init__.py
utils/
__init__.py
abc.py
projects/
__init__.py
proj1/
__init__.py
utils/
__init__.py
data_process.py
components/
__init__.py
class1.py
class2.py
Now, you can do a relative import like:
.
for importing something within the same directory. Example:# file Chatbot/projects/proj1/components/class2.py
from .class1 import *
..
for two-level, and ...
for three-level, and so on!For instance:
# file Chatbot/projects/proj1/components/class2.py
from ..utils.data_process import * # import from data_process.py
# there will be four "." earlier I made a counting mistake
from ....utils.abc import * # import something from abc.py
When writing a python module/package, you might want to follow PEP8 Convention.
Moreover, I believe you are trying to do different projects using your package Chatbot
, is that correct? Then, it is a good practice that you set PYTHONPATH
for Chatbot
and do all the projects, and imports seperately.
I'm able to work on this project seamlessly even with using two utils
directories. Project Structure:
main
file and its output:
# file main.py
from chatbot.utils.abc import hello as a1
from chatbot.projects.proj1.components.class1 import super_hello
from chatbot.projects.proj1.utils.data_process import hello as b1
print(a1(), b1())
print(super_hello())
Similarly, if you have a chatbot
under PYTHONPATH
you can call the project from anywhere from your device.
Code details and files are added to my github account for details.
Upvotes: 1
Reputation: 16486
sys.path
is where Python searches to find modules and packages and It does it in order.
So you can put ...../proj1/
at the beginning of the list, when python start searching it will find the utils
folder in that path first !
import sys
sys.path.insert(0, r'...../proj1/')
But this cause another problem, python always find utils
in that folder first, that's not what you want.
Absolute import:
from Chatbot.projects.proj1.utils.data_process import DataProcess
use relative imports which is mentioned by @Mr.Hobo.
Upvotes: 1