'Python script works in PyCharm but not in terminal

I'm currently trying to import one of my modules from a different folder. Like this...

from Assets.resources.libs.pout import Printer, ForeColor, BackColor

This import method works completely fine in PyCharm, however, when i try to launch the file in cmd or IDLE, i get this error.

ModuleNotFoundError: No module named 'Assets'

This is my file structure from main.py to pout.py:

- Assets
  - main.py
  - resources
    - libs
      - pout.py

Any clue about how i could fix this ? Any help is appreciated !



Solution 1:[1]

Edit: The original answer was based on the assumption that the script you're running is within the folder structure given, which a re-read tells me may not be true. The general solution is to do

sys.path.append('path_to_Assets')

but read below for more detail.

Original answer

The paths that modules can be loaded from will differ between the two methods of running the script.

If you add

import sys
print(sys.path)

to the top of your script before the imports you should be able to see the difference.

When you run it yourself the first entry will be the location of the script itself, followed by various system/environment paths. When you run it in PyCharm you will see the same first entry, followed by an entry for the top level of the project. This is how it finds the modules when run from PyCharm. This behaviour is controlled by the "Add content roots to PYTHONPATH" option in the run configuration.

Adding this path programmatically in a way that will work in all situations isn't trivial because, unlike PyCharm, your script doesn't have a concept of where the top level should be. BUT if you know you'll be running the script from the top level, i.e. your working directory will be the folder containing Assets and you're running something like python Assets/main.py then you can do

sys.path.append(os.path.abspath('.'))

and that will add the correct folder to the path.

Solution 2:[2]

Appending sys path didn't work for me on windows, hence here is the solution that worked for me:

Add an empty __init__.py file to each directory

i.e. in Assets, resources, libs. Then try importing with only the base package names. Worked for me!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Cierdo