0

Here's my directory structure:

my_package
|
+--__init__.py
|
+--setup.py
|
+--module.py
|
+--sub_package
   |
   +--__init__.py
   |
   +--script.py

The script script.py needs to import a function from module.py, and I need to be able to run script.py using the Python interpreter.

I know that Guido calls this an "anti-pattern". And I know you have 10 reasons why I shouldn't do this. I probably agree with most of them - really, I do. I wouldn't be asking this question if I could avoid this. So can we just skip the part where we go over why this is bad and move on to the solution? Thanks!

I also know that there are about a 1000 other SO questions about this. I've probably read them all by now. Most of them were made obsolete by changes to Python's import system, and the rest just aren't right.

What I have tried:

  • Using from .module import my_function in script.py and then either running python script.py inside the directory sub_package or python sub_package/script.py inside the directory my_package. Either way, I get the error:

SystemError: Parent module '' not loaded, cannot perform relative import

  • Using from module import my_function or from my_package.module import my_function and running script.py as above (either from sub_package or my_package). I get:

ImportError: No module named 'module'

(or similarly with my_package instead of module)

  • Running python -m sub_package/script from the directory my_package or python -m my_package/sub_package/script from the parent directory of my_package. I get:

No module named sub_package/script

(or similarly with my_package/sub_package/script)

Is there anything else I should be trying? I would really rather avoid messing with sys.path or PYTHONPATH for a whole host of reasons.

martineau
  • 119,623
  • 25
  • 170
  • 301
Paul Siegel
  • 1,401
  • 13
  • 36
  • can you write your function to __init__.py or parent module and then try to import my_function – Rakesh Kumar Jul 21 '16 at 03:31
  • Have you read [_Relative imports for the billionth time_](http://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time)? – martineau Jul 21 '16 at 03:32
  • @martineau Yes: that was one question that led to my 3rd attempt (`python -m ...`). The only other usable suggestion I saw in that involved messing with `sys.path` which is dangerous in general (and in the specific case which motivates this question). – Paul Siegel Jul 21 '16 at 03:43
  • Sometimes you have to do "dangerous" things to implement an anti-pattern...it could even be why some consider it a poor design. – martineau Jul 21 '16 at 03:46

2 Answers2

0

I believe you can just say

import module

from within script.py if you do the following:

from your terminal in the mypackage directory run:

$ python setup.py install

This will allow you to make the import statement that you want. The one issue that I have found with this method is that you will have to call

$ python setup.py install

every time you make a change to module.py but if you are ok with that this method should work

Graham Booth
  • 321
  • 3
  • 8
0

In fact, python interpreter will find module in sys.path.It means if you add your module's directory in this example "somepath/my_package" to sys.path, python will find it by "import module".

So how to achieve this goal?

If your directory absolute path never change, you can do this below:

sys.path.append(yourAbsPath)

But sometimes the path of directory might change, but the relative path will not change.So i recommend to follow this, try to add it to the beginning of your script.py:

import sys
import os
my_packagePath = os.path.dirname(os.path.dirname(__file__))
sys.path.append(my_packagePath)
import module
#from module import yourFunction #replace yourFunction with your real function 

In the cmd tool, just type "python yourScript.py's abspath".

jia hilegass
  • 493
  • 2
  • 12