Python Error while importing module from another directory

I've looked at so many stackoverflow posts but I don't understand why I'm getting this problem

My file system

parent_folder
    |folder1
        |module1.py
        |module2.py
        |__init__.py
    |folder2
        |main.py

I want to import module1.py and module2.py into main.py.

My __init__.py file has the following

__all__=['module1','module2']

Here is what I'm trying in main.py

from ..folder1 import *

But this give me this error:

Traceback (most recent call last):
File "main.py", line 2, in <module>
from ..folder1 import *
SystemError: Parent module '' not loaded, cannot perform relative import

I've been trying to solve this for an hour and nothing is working. Please help.


edit: I solved this by using absolute path (nothing else was working)

Upvotes: 0

Views: 4109

Answers (4)

LCoelho
LCoelho

Reputation: 3041

Here is what I came up as a solution:

To make is flexible to called from child folders and parent folder

import importlib
import sys
     

class MyClass:
            def __init__(self):
                sys.path.append('../folder1/')
                sys.path.append('../../folder1/')

When you need to use a class from an external a module, use something like this:

    mod = importlib.import_module('MyExternalModule')
    my_object = getattr(mod, 'MyExternalClass')

This is to answer to @noobycoder, but maybe is not the best practice. The best approach is to create a package for the external module and installed in your python environment.

Upvotes: 0

Nikhil Rupanawar
Nikhil Rupanawar

Reputation: 4191

Relative imports works with respect to your package. When you run python main.py simply it cant find what is current package

considering your path to parent folder is /path/up/to/parent_folder

execute

python -m parent_folder.folder2.main from /path/up/to   

OR

set PYTHONPATH or sys.path to /path/up/to/parent_folder, then change import to following

from folder2 import *

and execute python main.py

UPDATE

One of relative imports use case is to consume your package from script outside the package. This script usually acts as entry point or executable.

following is an example directory structure

myapp
│   entry.py
│
└───package
    │   __init__.py
    │   __init__.pyc
    │
    ├───folder1
    │       module1.py
    │       __init__.py
    │
    └───folder2
            start.py
            __init__.py

myapp/entry.py:

import sys
from package.folder2 import start

if __name__ == '__main__':
    sys.exit(start.main())

myapp/folder2/start.py:

import sys
from ..folder1.module1 import * 
# this is relative import to "package". 
# Use?: It will avoid confusion and conflicts with other packages in your syspath. Improve readability at some extent,

def main():
    print "do something with folder1.module1 imported objects"

and $ python entry.py

Upvotes: 1

shahzeb akram
shahzeb akram

Reputation: 926

I do it like this in python webapp2. Let me know if it helps.

from folder1.module1 import module1 #i did not try * but i hope it will also work.
from folder1.module2 import module2 #i did not try * but i hope it will also work.

Upvotes: 1

Zaid Khan
Zaid Khan

Reputation: 263

I prefer that you transfer folder1 to folder2 and then try

from folder1 import *

or maybe if you want keep the folders in that way you can try

import sys
sys.path.append("../") # or maybe sys.path.append("..")
from folder1 import *

this will add folder1 to your system path if you don't want to add to system path try

import os
os.chdir("../") #or maybe os.chdir("..")
from folder1 import *

I hope this the solution to your problem

Upvotes: 0

Related Questions