Search code examples
pythonpython-modulesys

Can't create a Module with __init__.py


I have 2 situations to import some files into the main script.
One works and the other doesn't and I can't tell the difference.

Scenario that works

main.py    
models  
├── __init__.py   
├── vggs.py  
├── resnets.py  

where __init__.py

from .vggs import *
from .resnets import *

and main.py

from models import *   # works fine

Scenario that doesn't work

scripts
├── main.py    
models  
├── __init__.py   
├── vggs.py  
├── resnets.py  

This time, I append the models folder to the sys.path in the main.py:

sys.path.append('../models')

# These don't work --> ModuleNotFoundError: No module name models
import models   
from models import * 

# However, these work
from vggs import *
from resnets import *

Why can I import each of the files but I cannot import the entire models folders as a module even I have the __init__.py?


Solution

  • You added the models directory itself to the sys.path list. Now Python looks for modules inside of that directory. There is no ../models/models/__init__.py nor is there a ../models/models.py, so import models fails.

    Add the parent directory to sys.path():

    sys.path.append('..')
    

    Python then finds ../models/__init__.py and so import models then succeeds.

    A much more robust version first determines the absolute path of the script/ directory then adds the parent path to sys:

    import os.path
    
    scripts_dir = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(os.path.dirname(scripts_dir))
    

    Otherwise, .. is relative to the current working directory, and that's not necessarily the scripts/ directory.