I am using Python 3 to try and get a test file for sample application working yet it keeps throwing ImportError: No module named 'calculate'
My file structure is:
/calculate
__init__.py
calculate.py
test/
__init__.py
calculate_test.py
I cannot figure out why this is the case, any help would be much appreciated.
The __init__.py files are empty.
calculate.py contains:
class Calculate(object):
def add(self, x, y):
return x + y
if __name__ == '__main__':
calc = Calculate()
result = calc.add(2, 2)
print(result)
calculate_test.py contains:
import unittest
from calculate import Calculate
class TestCalculate(unittest.TestCase):
def setUp(self):
self.calc = Calculate()
def test_add_method_returns_correct_result(self):
self.assertEqual(4, self.calc.add(2,2))
if __name__ == '__main__':
unittest.main()
I am running python test/calculate_test.py from the root /calculate folder and am getting the error
Traceback (most recent call last):
File "test/calculate_test.py", line 2, in <module>
from calculate import Calculate
ImportError: No module named 'calculate'
I have been fiddling around with different structures and cannot understand what the problem is.
Your project's structure is the reason. The test script doesn't have the outer directory in the search path when you start it. Here are some ways to fix that
Move the test file into the same directory that contains the module it imports. That will require no changes in the test file.
Use this structure
./project/
calculate_test.py
calculate/
__init__.py
calculate.py
This will require you to change the import signature in calculate_test.py to something like from calculate import calculate
Related
I have a Python project in which I have the following folder structure:
> root
> download_module
> __init__.py
> downloadProcess.py
> sharedFunctions.py
> someHelper.py
> useSharedFunction.py
The download_module/__init__.py has the following code:
from .sharedFunctions import stringArgumentToDate
from .downloadProcess import downloadProcessMethod
The sharedFunctions.py file contains the following function:
def stringArgumentToDate(arg):
dateformat = "%m/%d/%Y"
date = None
if arg.isnumeric():
date = datetime.fromtimestamp(int(arg))
if date == None:
date = datetime.strptime(arg, dateformat)
return date
Then on the useSharedFunction.py I try to import the shared function and use it like this.
from download_module import stringArgumentToDate
from download_module import downloadProcessMethod
def main():
arg = '03/14/2022'
dateArg = stringArgumentToDate(arg)
if __name__ == '__main__':
main()
When I try to run this by using python3 useSharedFunction.py I got the following error:
Traceback (most recent call last):
File "useSharedFunction.py", line 4, in <module>
from download_module import stringArgumentToDate
File "/Users/jacobo/Documents/project/download_module/__init__.py", line 2, in <module>
from .download_module import downloadAndProcessMethod
File "/Users/jacobo/Documents/project/download_module/downloadProcess.py", line 10, in <module>
from sharedFunctions import stringArgumentToDate, otherFunction
ModuleNotFoundError: No module named 'sharedFunctions'
I do believe the error is in downloadProcess since at the beggining of the file we got this import:
from sharedFunctions import stringArgumentToDate, otherFunction
from someHelper import Helper
Which refers to sibling files.
However I'm unsure what will be a proper fix to allow to run the downloadProcess.py main independently but also, being able to call it one of its method from a root or any other file out of the module.
Consider this structure:
┬ module
| ├ __init__.py
| ├ importing_submodule.py
| └ some_submodule.py
├ __main__.py
├ some_submodule.py
└ module_in_parent_dir.py
with content:
__main__.py
import module
/module/__init__.py
from . import importing_submodule
/module/importing_submodule.py
from some_submodule import SomeClass
/module/some_submodule.py
print("you imported from module")
class SomeClass:
pass
/some_submodule.py
print("you imported from root")
class SomeClass:
pass
/module_in_parent_dir.py
class SomeOtherClass:
pass
How sibling import works
(skip this section if you know already)
Now lets run __main__.py and it will say "you imported from root".
But if we change code a bit..
/module/importing_submodule.py
from module.some_submodule import SomeClass
It now says "You imported from module" as we wanted, probably with scary red line in IDE saying "Unresolved reference" if you didn't config working directory in IDE.
How this happen is simple: script root(Current working directory) is decided by main script(first script that's running), and python uses namespaces.
Python's import system uses 2 import method, and for convenience let's call it absolute import and relative import.
Absolute import: Import from dir listed in sys.path and current working directory
Relative import: Import relative to the very script that called import
And what decide the behavior is whether we use . at start of module name or not.
Since we imported by from some_submodule without preceeding dot, python take it as 'Absolute import'(the term we decided earlier).
And then when we also specified module name like from module.some_submodule python looks for module in path list or in current working directory.
Of course, this is never a good idea; script root can change via calls like os.chdir() then submodules inside module folder may get lost.
Therefore, the best practices for sibling import is using relative import inside module folder.
/module/importing_submodule.py
from .some_submodule import SomeClass
Making script that work in both way
To make submodule import it's siblings when running as main script, yet still work as submodule when imported by other script, then use try - except and look for ImportError.
For importing_submodule.py as an example:
/module/importing_submodule.py
try:
from .some_submodule import SomeClass
except ImportError:
# attempted relative import with no known parent package
# because this is running as main script, there's no parent package.
from some_submodule import SomeClass
Importing modules from parent directory is a bit more tricky.
Since submodule is now main script, relative import to parent level directory doesn't work.
So we need to add the parent directory to sys.path, when the script is running as main script.
/module/importing_submodule.py
try:
from .some_submodule import SomeClass
except ImportError:
# attempted relative import with no known parent package
# because this is running as main script, there's no parent package.
from some_submodule import SomeClass
# now since we don't have parent package, we just append the path.
from sys import path
import pathlib
path.append(pathlib.Path(__file__).parent.parent.as_posix())
print("Importing module_in_parent_dir from sys.path")
else:
print("Importing module_in_parent_dir from working directory")
# Now either case we have parent directory of `module_in_parent_dir`
# in working dir or path, we can import it
# might need to suppress false IDE warning this case.
# noinspection PyUnresolvedReferences
from module_in_parent_dir import SomeOtherClass
Output:
"C:\Program Files\Python310\python.exe" .../module/importing_module.py
you imported from module
Importing module_in_parent_dir from sys.path
Process finished with exit code 0
"C:\Program Files\Python310\python.exe" .../__main__.py
you imported from module
Importing module_in_parent_dir from working directory
Process finished with exit code 0
This question already has answers here:
Relative imports for the billionth time
(12 answers)
Closed 1 year ago.
Here's a file structure I'm working with:
package_example/
main.py
the_package/
__init__.py
pkg_file_1.py
pkg_file_2.py
Here are the files:
# main.py
from the_package.pkg_file_1 import foo_1
def main():
foo_1()
if __name__ == "__main__":
main()
# pkg_file_1.py
from the_package import pkg_file_2
def foo_1():
print("this is the second version, foo_1")
pkg_file_2.foo_2()
if __name__ == "__main__":
foo_1()
# pkg_file_2.py
def foo_2():
print("this is foo_2")
If I run main.py, everything works fine.
But if I run pkg_file_1.py, I get:
Traceback (most recent call last):
File "the_package/pkg_file_1.py", line 1, in <module>
from the_package import pkg_file_2
ModuleNotFoundError: No module named 'the_package'
Obviously in this simplified example, it doesn't matter, since main.py and pkg_file_1.py run the same code.
But practically, I have test scripts baked into my package structure, so I can test the code in my new environment and data. But I'm scratching my head on how I'm supposed write import statements such that I don't get a ModuleNotFoundError from both inside or outside the package.
Edit: From pavel's suggest I tried changing pkg_file_1.py to:
from ..the_package import pkg_file_2
def foo_1():
print("this is the second version, foo_1")
pkg_file_2.foo_2()
if __name__ == "__main__":
foo_1()
But running that same file gives:
Traceback (most recent call last):
File "the_package/pkg_file_1.py", line 1, in <module>
from ..the_package import pkg_file_2
ImportError: attempted relative import with no known parent package
This is why we need relative import.
# pkg_file_1.py
from . import pkg_file_2
...
How to run main.py and pkg_file1.py from package_example dir:
python3 main.py
python3 -m the_package.pkg_file1
I have the following 4 python files within the folder SubFolder, assembled as such:
CodeFolder
SubFolder
GeneticAlgorithm.py
main.py
heuristic1.py
heuristic2.py
I am trying to import the file GeneticAlgorithm.py within my main.py file, using the import statement at the beginning of the class:
import GeneticAlgorithm
The problem: PyCharm is highlighting this and says "no module named GA".
Any clues as to what may be causing this issue and how to solve it? Thank you!
Correct me if I'm wrong but you might not have GA module in your GeneticAlgorithm.py
If you do, then you can do similar to below:
Similar to your folder structure:
From main.py call GeneticAlgorithm.py. For example:
from GeneticAlgorithm import GA
def main():
ga_obj = GA(mutation_rate=0.5)
print("Call GA module")
if __name__ == '__main__':
main()
If we look at the GeneticAlgorithm.py
class GA:
def __init__(self, mutation_rate):
self.mutation = mutation_rate
We have GA class.
This is a simple demonstration of how you can use.
I've tried this from so many different angles but can't sort it out. Must be such a simple case. In Python 3.7.6:
Directory structure:
./modtest/
./modtest/__init__.py
./modtest/test1.py
./modtest/test2.py
test1.py:
import modtest
def x(i):
print(i)
y(i)
test2.py:
def y(i):
print(i)
__init__.py is an empty file.
When I attempt to run the code:
$ /Users/pitosalas/miniconda3/bin/python /Users/pitosalas/mydev/rsb_py/modtest/test1.py
Traceback (most recent call last):
File "/Users/pitosalas/mydev/rsb_py/modtest/test1.py", line 1, in <module>
import modtest
ModuleNotFoundError: No module named 'modtest
From what I read this should've worked. I'm sure there's something trivial wrong!
You are importing modtest in test1.py while this module itself resides inside of modtest. This can't be because modest wouldn't have yet been defined and added to the search path. So this is what you should have actually:
./modtest/
./modtest/__init__.py
./modtest/
./modtest/test2.py
./test1.py # this module must be outside of modtest
i want to make a sample package in python 2.7 just to clear my concepts whose structure looks like this:
calculator/
main.py
operations/
file1.py
file2.py
__init__.py
new_operations/
__init__.py
file3.py
main.py content: (this file is present inside calculator folder)
from operations import power
print power(2,2)
__init__.py content: (this file is present inside operations folder)
from .file1 import add
from .file1 import sub
from .file2 import mul
from .file2 import div
file1.py content: (this file is present inside operations folder)
def add(a,b):
return(a+b)
def sub(a,b):
return(a-b)
file2.py content: (this file is present inside operations folder)
def mul(a,b):
return(a*b)
def div(a,b):
return(a/b)
__init__.py content: (this file is present inside new_operations folder)
from .file3 import power
file3.py content: (this file is present inside new_operations folder)
def power(a,b):
return(a**b)
Now, when i run main.py, i got following error:
Traceback (most recent call last):
File "C:\Python27\mycodes\calculator\main.py", line 3, in <module>
from operations import power
ImportError: cannot import name power
Can anyone tell me, what mistake i am doing ? Help me.
Use the following line in your "main.py" file:
from operations.new_operations import power
You are missing an 'add' function in your calculator module. If you create an 'add' function, I would assume that the code would work.
maybe try doing this in the module calculator:
def add(num1,num2):
print(num1+num2)
return num1+num2;
If you don't want it to print while calculating, remove the print statement.
Hope this helps!