Can't import my own modules in Python
Asked Answered
D

15

205

I'm having a hard time understanding how module importing works in Python (I've never done it in any other language before either).

Let's say I have:

myapp/__init__.py
myapp/myapp/myapp.py
myapp/myapp/SomeObject.py
myapp/tests/TestCase.py

Now I'm trying to get something like this:

myapp.py
===================
from myapp import SomeObject
# stuff ...

TestCase.py
===================
from myapp import SomeObject
# some tests on SomeObject

However, I'm definitely doing something wrong as Python can't see that myapp is a module:

ImportError: No module named myapp
Dissent answered 21/2, 2012 at 18:27 Comment(1)
While the answers to this question explain how to solve the problem, the reason is explained here: #24436197Bryology
T
140

In your particular case it looks like you're trying to import SomeObject from the myapp.py and TestCase.py scripts. From myapp.py, do

import SomeObject

since it is in the same folder. For TestCase.py, do

from ..myapp import SomeObject

However, this will work only if you are importing TestCase from the package. If you want to directly run python TestCase.py, you would have to mess with your path. This can be done within Python:

import sys
sys.path.append("..")
from myapp import SomeObject

though that is generally not recommended.

In general, if you want other people to use your Python package, you should use distutils to create a setup script. That way, anyone can install your package easily using a command like python setup.py install and it will be available everywhere on their machine. If you're serious about the package, you could even add it to the Python Package Index, PyPI.

Truism answered 21/2, 2012 at 18:46 Comment(6)
I tried simply using import in my TestCase.py but it still gave me the same error. I'm assuming it's because its in a sub-directory of the __init__.py?Dissent
Oh wait I think I get it. If my test cases are calling from the package, I'll be able to use the from ... import ... right?Dissent
You will only if TestCase is being imported from outside the package- for example, if I run from myapp.tests import TestCase from a script outside myapp. If you're running python TestCase.py` within the tests folder you can't do relative importsTruism
I ran "pip install -e . " to install myapp, but when trying to run TestCase in visual studio code I still get "ImportError: No module named myapp". but if I run "python" and then in python run "from myapp import SomeObject" it works. What am I doing wrong?Fanfani
@DavidRobinson I used the method you have mentioned, that showed no error after executing from fodername import file_name_of_my_py_code, but when I tried to access the object defined in file_name_of_my_py_code.py it says NameError: name 'ClassName' is not definedHuonghupeh
Doing import sys and setting sys.path.append("..")... Does this set the path globally or only for that session when we are using the Python Interpreter? @DavidRobinsonHuonghupeh
M
55

The function import looks for files into your PYTHONPATH env. variable and your local directory. So you can either put all your files in the same directory, or export the path typing into a terminal::

export PYTHONPATH="$PYTHONPATH:/path_to_myapp/myapp/myapp/"
Mini answered 21/2, 2012 at 18:31 Comment(4)
Then how can I make sure it works for everyone else who would use it? I'd rather not have to tell them to set certain environment variables before running it.Dissent
the current directory is in pythonpath, so as long as the scripts are in the same folder/directory it should work. unfortunately each of these scripts are in separate directories.Sokol
For Windows users, instead of export we have "set PYTHONPATH=%PYTHONPATH%;C:\path_to_myapp\myapp\myapp\"Hemialgia
In vs code I was able to fix this by adding PYTHONPATH Env variable to my launch.json:"env": { "PYTHONPATH": "${workspaceFolder}" }Lessen
W
15

You can try

from myapp.myapp import SomeObject

because your project name is the same as the myapp.py which makes it search the project document first

Wychelm answered 6/3, 2017 at 13:54 Comment(0)
A
14

exporting path is a good way. Another way is to add a .pth to your site-packages location. On my mac my python keeps site-packages in /Library/Python shown below

/Library/Python/2.7/site-packages

I created a file called awesome.pth at /Library/Python/2.7/site-packages/awesome.pth and in the file put the following path that references my awesome modules

/opt/awesome/custom_python_modules
Aerial answered 20/5, 2013 at 23:36 Comment(4)
in the case i am working in windows how do i do thatSeguidilla
I'm not sure. In the case that you are using windows. Find some vm software and use linux. Or - see this answer on exporting variables in windows. #560316Aerial
this is exactly what i neededDessau
Happy to hear that @Dessau - took me a while to figure it out myself :)Aerial
M
10

You need to have

__init__.py

in all the folders that have code you need to interact with. You also need to specify the top folder name of your project in every import even if the file you tried to import is at the same level.

Mortgage answered 5/6, 2020 at 15:42 Comment(0)
H
6

In your first myapp directory ,u can add a setup.py file and add two python code in setup.py

from setuptools import setup
setup(name='myapp')

in your first myapp directory in commandline , use pip install -e . to install the package

Heartwhole answered 28/10, 2017 at 11:30 Comment(0)
I
3

pip install on Windows 10 defaults to installing in 'Program Files/PythonXX/Lib/site-packages' which is a directory that requires administrative privileges. So I fixed my issue by running pip install as Administrator (you have to open command prompt as administrator even if you are logged in with an admin account). Also, it is safer to call pip from python.
e.g.
python -m pip install <package-name>
instead of
pip install <package-name>

Isoclinal answered 21/8, 2018 at 9:12 Comment(1)
you made my day. To others .. this is important if you have lot of local modules. Local module is used by other local module you need to install your local module first and make it part of your import list for other module. Easy but took long time for me to grasp the module concept.Deviation
C
2

let's say i write a module

import os
my_home_dir=os.environ['HOME'] // in windows 'HOMEPATH'
file_abs_path=os.path.join(my_home_dir,"my_module.py")

with open(file_abs_path,"w") as f:
   f.write("print('I am loaded successfully')")

import importlib
importlib.util.find_spec('my_module') ==> cannot find

we have to tell python where to look for the module. we have to add our path to the sys.path

 import sys
 sys.path.append(file_abs_path)

now importlib.util.find_spec('my_module') returns:

  ModuleSpec(name='my_module', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7fa40143e8e0>, origin='/Users/name/my_module.py')

we created our module, we informed python its path, now we should be able to import it

 import my_module

//I am loaded successfully
Crab answered 14/9, 2020 at 2:9 Comment(0)
C
2

Short Answer:

python -m ParentPackage.Submodule

Executing the required file via module flag worked for me. Lets say we got a typical directory structure as below:

my_project:
 | Core
    ->myScript.py
 | Utils
   ->helpers.py
 configs.py

Now if you want to run a file inside a directory, that has imports from other modules, all you need to do is like below:

python -m Core.myscript

PS: You gotta use dot notation to refer the submodules(Files/scripts you want to execute). Also I used python3.9+. So I didnt require neither any init.py nor any sys path append statements.

Hope that helps! Happy Coding!

Calamity answered 29/8, 2021 at 13:23 Comment(0)
S
0

In my case it was Windows vs Python surprise, despite Windows filenames are not case sensitive, Python import is. So if you have Stuff.py file you need to import this name as-is.

Silencer answered 17/5, 2018 at 9:31 Comment(0)
W
0

This worked for me:

from .myapp import SomeObject

The . signifies that it will search any local modules from the parent module.

Wittie answered 30/5, 2022 at 3:58 Comment(0)
G
0

If you are using the IPython Console, make sure your IDE (e.g., spyder) is pointing to the right working directory (i.e., your project folder)

Goodill answered 18/11, 2022 at 15:16 Comment(0)
A
0

Besides the suggested solutions like the accepted answer, I had the same problem in Pycharm, and I didn't want to modify imports like the relative addressing suggested above.

I finally found out that if I mark my src/ (root directory of my python codes) as the source in Interpreter settings, the issue will be resolved.

In the settings

enter image description here

Adhesion answered 25/12, 2022 at 13:57 Comment(0)
O
0

I added my custom modules path to python3*._pth file.It will be located in the python installed directory.

This resolved the issue

Oleaster answered 27/7, 2023 at 7:25 Comment(0)
G
-1

If you use Anaconda you can do:

conda develop /Path/To/Your/Modules

from the Shell and it will write your path into a conda.pth file into the standard directory for 3rd party modules (site-packages in my case).

Groningen answered 5/8, 2022 at 21:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.