İmport a python function inside a subfolder

  • Context: Python 
  • Thread starter Thread starter Arman777
  • Start date Start date
  • Tags Tags
    Function Python
Click For Summary

Discussion Overview

The discussion revolves around how to import a Python function from a file located in a parent directory into a script located in a subfolder. Participants explore various methods of achieving this, including the use of relative imports and the importlib module, while addressing issues related to module visibility and path management.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Exploratory

Main Points Raised

  • One participant describes their project structure and attempts to import functions from my_functions.py into test.py using various import statements, encountering a ModuleNotFoundError.
  • Another participant suggests using importlib to dynamically import the module, providing a code snippet for this method.
  • Some participants propose using relative imports, but one notes an ImportError related to the parent package.
  • A suggestion is made to create an empty __init__.py file in the Projects directory to facilitate imports, but this does not resolve the issue for all participants.
  • One participant mentions adding the parent directory to sys.path as an alternative solution, indicating that this method works for them.
  • Discussions arise regarding potential issues related to the operating system (Windows) and Python version differences affecting import behavior.
  • Another participant clarifies that the execution context of the script (the directory from which it is run) affects the import paths, suggesting modifications to sys.path for broader compatibility.

Areas of Agreement / Disagreement

Participants express differing views on the necessity of __init__.py files and the effectiveness of various import methods. There is no consensus on a single solution, as some methods work for certain participants while others continue to face issues.

Contextual Notes

Limitations include unresolved issues with relative imports and module visibility, as well as dependencies on the execution context and Python version. The discussion reflects a range of experiences and solutions without a definitive resolution.

Arman777
Insights Author
Gold Member
Messages
2,163
Reaction score
191
I have a project folder called Projects and inside that folder I have a file called my_functions.py. Now I have a folder named Project 1
and inside there is another python file called test.pySo it is something like

-Projects-
my_functions.py
-Project 1-
test.py

Now I have some functions in the my_functions.py file such as f1, f2 etc.

Now, I need to take a function from my_functions.py and use it inside the test.py

I have used things like

from my_functions import f1
from .my_functions import f1
from Projects.my_functions import f1

For the first one I get an error called

ModuleNotFoundError: No module named 'my_functions'

I have searched online and I find that I need to do something about _init_.py somewhere (?) The problem is, I am new in codding so I could not find where to put that module, in what way etc. So if someone can tell me what to do step by step it would be really helpful.
Thanks Thanks
 
Technology news on Phys.org
Based on this example on the importlib documentation:

Python:
import importlib.util
import sys

module_name = 'my_functions'
file_path = '/path/to/Projects/my_functions.py'

spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)

# This should now work:
my_functions.f1

# This may or may not work
from my_functions import f1
 
pasmith said:
Based on this example on the importlib documentation:

Python:
import importlib.util
import sys

module_name = 'my_functions'
file_path = '/path/to/Projects/my_functions.py'

spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)

# This should now work:
my_functions.f1

# This may or may not work
from my_functions import f1
Is there a simpler way..?
 
Arman777 said:
attempted relative import with no known parent package
You need to create an empty __init__.py file in Projects.
 
Still gives an error..interesting
 
Hmm, you may need __init__.py in Project 1 too
 
Nope..it doest not work
 
  • #10
1606746852083.png


This is how it looks like. I need to write something that takes a function from my_functions and works in the test.py
 
  • #11
Oh, right. You shouldn't need the __init__.py, you just need to add the parent directory to sys.path, either from the command line or in code:
Python:
# myProjects/test.py
import sys
sys.path.insert(0, '..')
from my_functions import f1
 
  • #12
It does not work
 
  • #13
It does for me.

Screenshot at 2020-11-30 16-04-09.png


If you want it to work for you too then you need to be more specific.
 
  • #14
Its really interesting. It still says

ModuleNotFoundError: No module named 'my_functions'
 
  • #15
Could possibly be a Windows issue - I don't have access to a Windows machine with Python on until later today. Or possibly a Python version issue: relative imports did change in about v3.3 I think (as you can see that example is running in 3.8.5).
 
  • #16
I am running 3.9. I am also using Windows. Maybe yeah...
 
  • #17
Just tested it in Windows, it works for me there too - then I realized why. I am running test.py from the myProjects folder using python test.py. I think you are running it from the parent folder using python myProjects/test.py.

Paths in python scripts are relative to the path python is run from, not the path of the current file. You could either run it from the project folder or change the path command to sys.path.insert(0, '.'), but the best way to fix it so you can run it from anywhere is
Python:
# myProjects/test.py

from os.path import dirname, join
import sys

sys.path.insert(0, join(dirname(__file__), '..'))

from my_functions import f1

print(f1(1))
 
  • Like
  • Informative
Likes   Reactions: mfb, jim mcnamara, Wrichik Basu and 1 other person
  • #18
This time it works, thanks a lot.
 

Similar threads

  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 16 ·
Replies
16
Views
5K
  • · Replies 14 ·
Replies
14
Views
8K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 25 ·
Replies
25
Views
6K
Replies
6
Views
3K
  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 9 ·
Replies
9
Views
2K