0

I have a local python code repo like the following. In python/foo/code.py I want to import target_module in foo/bar/baz/target_module. However, because code.py is under the foo module, I cannot import target_module. Since it's a largish repo with a great deal of legacy code, I cannot easily change any directory name. Is there any other workaround?

Thanks in advance!

|──foo
|   ├──bar
|         ├──baz
|               ├── target_module
├── python
|   ├── foo
|   │   ├── code.py      <----from foo.bar.baz.target_module import *
3
  • checkout importlib Commented Sep 19, 2018 at 22:04
  • You shouldn't be having this problem if you're using python 3 Commented Sep 19, 2018 at 22:16
  • @MadPhysicist The OP would have the problem if it's not really a python package (.e. no __init__.pys) and it's just a bunch of directories with some python scripts. All bets are off in legacy Commented Sep 19, 2018 at 22:22

1 Answer 1

1

There a couple ways you can do this. The quick and dirty is to just add it to your interpreter's path.

Here's my setup:

Matthews-MacBook-Pro:test_project matt$ tree
.
├── foo
│   └── bar
│       └── baz
│           └── target_module.py
└── python
    └── foo
        └── code.py

5 directories, 2 files

Here's the contents of target_module.py:

def my_func():
    print("my func called.")

and how you can import this function into code.py:

import os
import sys

# Cheat and just add it to python interpreter's path                                                                                                                                                        
this_dir = os.path.dirname(__file__)
sys.path.append(os.path.join(this_dir, "..", "..", "foo", "bar", "baz"))

import target_module as tm
tm.my_func()

this outputs:

Matthews-MacBook-Pro:test_project matt$ python python/foo/code.py 
my func called.

or you can call it from the foo directory and it'll still work fine:

Matthews-MacBook-Pro:test_project matt$ cd python/foo/
Matthews-MacBook-Pro:foo matt$ python code.py 
my func called.

You can also just add the foo/bar/baz directory to your PYTHONPATH environment variable instead of calling sys.path.append. This syntax is shell dependent: so I'll let you google how to set environment variables for your particular shell.

Ideally you'd want to make your modules deployable (i.e. use setup.py and distutils or setuptools and put __init__.py in each module), and then you can import "normally" (kind of like you can "just" import numpy and it works). But since you claim it's legacy, maybe this might be hard for you to accomplish. I get it: in legacy systems all bets are off and sometimes the quick and dirty is fine (and maybe even ideal if you don't want to spend a lot of time fixing the issue).

I can expand this answer if you're interested in creating deployable python packages, and if not, the above should get the job done.

HTH.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi Matt, thank you so much for your solution. As you said, this quick method does work. However, i do need the method to make the code deployable. The reason I mentioned legacy is that there are many people working on this repo and there're are reasons I cannot change the dir name with reasonable efforts. It would be great if you can share the method that can create deployable package. Thanks!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.