Fidd
Fidd

Reputation: 722

Import module does not work through terminal, while it works through IDE

I have a projects consisting of two packages like this:

MyProjectDir
-Package1
--__init__.py
--file1_1.py
--file1_2.py
--file1_3.py
-Package2
--__init__.py
--file2_1.py
--file2_2.py
--file2_3.py

Now, in the packages the files have some imports between files:

file2_3.py:

from Package2.file2_1 import *
run_some_code()

When I run file2_3.py directly from PyCharm, everything runs ok. But when I try to run the script in the terminal (I'm working on Windows 7):

D:\SVN Repo\MyProjectDir\Package2> python file2_3.py

or alternatively

D:\SVN Repo\MyProjectDir> python ./Package2/file2_3.py

It seems python can't see my packages and I get an error:

Traceback (most recent call last):
  File "./Package2/file2_3.py", line 1, in <module>
    from Package2.file2_1 import *
ImportError: No module named 'Package2'

What is the reason?

EDIT: If in the import line I use from file2_1.py import * without the package name, the IDE underlines the import as "Unresolved Reference Package2" (though it can run), and the terminal works...

Upvotes: 5

Views: 3142

Answers (1)

Bakuriu
Bakuriu

Reputation: 101909

The issue is that the way in which you are running the program is wrong, PyCharm is aware on how to handle python submodules and thus executes the file correctly.

If you have a package package1 with a module package1.my_module you should run this using the -m switch:

python -m package1.my_module

Do not run it directly:

python package1/my_module.py   <-- NO! Incorrect

Also: you should run the file from outside the package. So if your project is:

MyProject
  |
  +- package1
  |   |
  |   +- file1.py
  |
  +- package2
      |
      +- file2.py

Your working directory should be MyProject.

My personal advice: never run submodules directly. Instead put the code in a separate script that is outside the package. So I'd have:

MyProject
  |
  +- package1
  |   |
  |   +- file1.py
  |
  +- package2
  |   |
  |   +- file2.py
  |
  +- scripts
      |
      +- script1.py

Where script1.py imports the modules it needs:

from package1 import file1
from package2 import file2

# code

Then you can run that script from your MyProject directory:

python scripts/script1.py

When you want to deploy your code you'll write a setup.py scripts that adds package1 and package2 as packages while script1.py as a script and they will be installed in the correct directories so that you'll be able to import package1 and package2 from everywhere and run script1.py from everywhere.

Upvotes: 7

Related Questions