JohnNil
JohnNil

Reputation: 33

python local module with same

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 *

Upvotes: 0

Views: 58

Answers (1)

Matt Messersmith
Matt Messersmith

Reputation: 13747

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.

Upvotes: 1

Related Questions