777

How do I import a Python module given its relative path?

For example, if dirFoo contains Foo.py and dirBar, and dirBar contains Bar.py, how do I import Bar.py into Foo.py?

Here's a visual representation:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Foo wishes to include Bar, but restructuring the folder hierarchy is not an option.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Jude Allred
  • 10,577
  • 7
  • 25
  • 27
  • 3
    Looks like http://stackoverflow.com/questions/72852/how-to-do-relative-imports-in-python, maybe? – Joril Nov 10 '08 at 23:44
  • 3
    Check my answer, it is the most complete so far, others are not working in special case, for example when you call the script from another directory or from another python script. See http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder/6098238#6098238 – sorin May 26 '11 at 06:17
  • I had a similar problem and I found this and it works!! apt-get install python-profiler – ldcl289 Sep 22 '11 at 20:18
  • 5
    Just in case somebody wants to do it statically and gets here (like I did :) you can also set up the PYTHONPATH environment variable – okaram Jan 10 '15 at 21:23
  • Better is to follow the instructions in Lib/site.py for each case – Avenida Gez Apr 01 '15 at 15:15

22 Answers22

342

Assuming that both your directories are real Python packages (do have the __init__.py file inside them), here is a safe solution for inclusion of modules relatively to the location of the script.

I assume that you want to do this, because you need to include a set of modules with your script. I use this in production in several products and works in many special scenarios like: scripts called from another directory or executed with python execute instead of opening a new interpreter.

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # Use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if the script is called in different ways on Windows.
 # __file__ fails if someone does os.chdir() before.
 # sys.argv[0] also fails, because it doesn't not always contains the path.

As a bonus, this approach does let you force Python to use your module instead of the ones installed on the system.

Warning! I don't really know what is happening when current module is inside an egg file. It probably fails too.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
sorin
  • 137,198
  • 150
  • 472
  • 707
  • 6
    can I get an explanation as to how this works? I've got a similar problem and I'd LOVE to force a python module DIR instead of running a search – carl crott Jan 15 '12 at 12:53
  • Running Win 7 Pro 64x and Python 2.7 I get a few errors. 1) I had to add inspect to the import list. 2) The 1st value, [0], in the tuple is an empty string. The 2nd, [1], shows the file name. I am guessing that the first should be the path... Any ideas? – Adam Lewis Jan 17 '12 at 05:38
  • 2
    If you are going for a subfolder, use it like this:`os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]) + "/subfolder")` Do _NOT_ add the subfolder before `abspath` as this causes serious bugs. – Maximilian Hils Jul 12 '12 at 22:39
  • 4
    @scr4ve you should use os.path.join() instead, and you are welcome to add the case (`cmd_subfolder`) directly to my answer. thanks! – sorin Jul 13 '12 at 12:32
  • 8
    for me `realpath` already generates absolute paths, thus I don't need `abspath`. Also `os.path.dirname` can be used instead of split, makeing the indexing `[0]` obsolete. The line would then be: `os.path.realpath(os.path.dirname(inspect.getfile(inspect.currentframe())))` – ted Aug 14 '12 at 07:37
  • `inspect.currentframe()` is a "CPython implementation detail" (https://docs.python.org/2/library/inspect.html#inspect.currentframe), so it can fail too… – Eric O Lebigot Jul 10 '14 at 10:32
  • What concrete cases does "__file__ fails if script is called in different ways on Windows" refer to? – Eric O Lebigot Jul 10 '14 at 10:34
  • does this answer requires an upgrade for python 3.4 ? – Praneeth Jun 11 '15 at 16:23
  • Something to keep in mind for using the `inspect` module for those who may disable the GC in their scripts: [note on reference cycles](https://docs.python.org/2/library/inspect.html#the-interpreter-stack). – rob Mar 07 '16 at 18:49
  • Love the solution, but pylint doesn't. Anyone know of a good way to make pylint shut up? – James Puderer Jan 24 '19 at 01:13
  • This is awful advice since the introduction of relative imports, which was well before this answer was written. – jpmc26 Apr 03 '19 at 03:41
  • This article explains it better https://realpython.com/absolute-vs-relative-python-imports/ —- keep in mimd that the final answer may depend on the range of python versions you are targeting. – sorin Apr 03 '19 at 06:15
  • This made my pytest work out. New issue: now mypy complains about getfile having incompatible type "Optional[FrameType]"; expected "Union[Module, Type[Any], MethodType, FunctionType, TracebackType, FrameType, CodeType, Callable[..., Any]]" – Ollie Jul 09 '20 at 08:15
329

Be sure that dirBar has the __init__.py file -- this makes a directory into a Python package.

S.Lott
  • 359,791
  • 75
  • 487
  • 757
  • 204
    Note that this file can be completely empty. – Harley Holcombe Nov 10 '08 at 22:00
  • 48
    If dirBar's parent directory is not in `sys.path` then the presence of `__init__.py` in the `dirBar` directory doesn't help much. – jfs Nov 10 '08 at 22:40
  • 1
    The above comment assumes that dirBar is a sub-package. – jfs Nov 10 '08 at 23:11
  • 8
    -1, adding `__init.py__` will work only when directory is already in sys.path and in my case it wasn't. Solution by "sorin" (accepted one) always works. – Czarek Tomczak Nov 22 '11 at 23:27
  • 12
    "when directory is already in sys.path". While totally true, how could we guess that the directory was not in `sys.path` from the question? Perhaps there was something omitted that we didn't see or know about? – S.Lott Nov 23 '11 at 00:47
  • 1
    Additional context: `__init__.py` is just a token that tells Python that you actually want to be able to use the folder with `import` (the default is "no" in order to prevent accidental namespace corruption). – Brent Bradburn Dec 20 '12 at 01:32
  • Although not necessarily an ideal solution in all cases, this works very well for purposes such as module organization. Thank you! – Tiffany Feb 16 '15 at 02:53
  • 4
    This is by NO means the answer to the question: whether or not the initialisation file is there, this doesn't make python look into the sub-directories. How did it get hundreds of upvotes? – gented Apr 03 '17 at 16:15
  • These comments are useful though - this is the first time I see stipulated that I need **both** `__init__.py` **and** the (parent directory of my) top directory in my `PYTHONPATH` environment variable. – AstroFloyd May 20 '21 at 07:25
264

You could also add the subdirectory to your Python path so that it imports as a normal script.

import sys
sys.path.insert(0, <path to dirFoo>)
import Bar
Louis Maddox
  • 4,311
  • 5
  • 28
  • 59
Andrew Cox
  • 9,902
  • 2
  • 31
  • 38
  • 6
    It looks that your answer does not work with relative paths, see http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder/6098238#6098238 – bogdan May 23 '11 at 14:03
  • 24
    This *does* work with relative paths -- you just need to understand that a relative path will depend on what directory you run from, which makes this a poor solution for anything other than a quick hack. – Brent Bradburn Dec 20 '12 at 01:11
  • 12
    You can do something like `sys.path.append(os.path.dirname(__file__) + "/relative/path/to/module")` – Falko Nov 06 '15 at 12:43
  • or `sys.path.append(__name__ if __name__ != '__main__' else __loader__.fullname)` – vim Jan 18 '17 at 12:42
  • 1
    Consider using `sys.path.insert(0, )` as it will load this module before the same-name modules stored elsewhere. – Anton Tarasenko Oct 29 '17 at 13:33
118
import os
import sys
lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib'))
sys.path.append(lib_path)

import mymodule
Brian
  • 677
  • 6
  • 13
lefakir
  • 3,975
  • 3
  • 25
  • 37
  • 2
    I like this because you have the flexibility to go up a directory. – Charles L. Aug 10 '11 at 21:55
  • 21
    You should use `os.path.join()` instead of joining by '/', which will break in the (lame) windows. – 0xc0de Aug 02 '12 at 06:58
  • 18
    This isn't reliable. It depends on whatever the current working directory is, not on the directory that the script lives. – jamesdlin Jan 31 '14 at 10:00
  • May want to only add if the path is not already in the path. lib_path = os.path.abspath('../functions') if lib_path not in sys.path: sys.path.append(lib_path) – Brent Aug 15 '14 at 19:12
  • in reply to @jamesdlin combining a few answers: what about `os.path.abspath(os.path.join(__file__,'..','lib'))`? – Matthew Davis Jan 03 '18 at 18:36
  • @MatthewDavis I suppose that works, but it feels really wrong to use a filename as a directory like that (and then to discard it with ".."). I'd personally prefer using `os.path.dirname(__file__)` first. – jamesdlin Jan 03 '18 at 23:06
  • Fair point. I see the only advantage with the `'..'` approach is the succinct chaining: `os.path.join(__file__, '..', '..', '..', 'lib')` to reach multiple levels up. I suppose the most clear would be: `os.path.join(os.path.dirname(__file__), '..', '..', 'lib')`, but that feel redundant. Thoughts? – Matthew Davis Jan 09 '18 at 18:14
109

Just do simple things to import the .py file from a different folder.

Let's say you have a directory like:

lib/abc.py

Then just keep an empty file in lib folder as named

__init__.py

And then use

from lib.abc import <Your Module name>

Keep the __init__.py file in every folder of the hierarchy of the import module.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Deepak 'Kaseriya'
  • 1,138
  • 1
  • 7
  • 3
78

If you structure your project this way:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

Then from Foo.py you should be able to do:

import dirFoo.Foo

Or:

from dirFoo.Foo import FooObject

Per Tom's comment, this does require that the src folder is accessible either via site_packages or your search path. Also, as he mentions, __init__.py is implicitly imported when you first import a module in that package/directory. Typically __init__.py is simply an empty file.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
bouvard
  • 3,766
  • 22
  • 28
  • Also mention that __init__.py is imported when the first module inside that package is imported. Also, your example will only work if src is in the site_packages (or in the search path) – Tom Leys Nov 10 '08 at 22:00
  • 3
    This is the most simplest solution I was looking for. If the file to import is sure to be in one of the subdirectories, this solution is a gem. – Deepak G M Dec 31 '12 at 08:59
  • I have tried the same thing and fail. I do not know why. ImportError: No module named customMath – Ming Li Mar 05 '14 at 12:09
  • 10
    Why would someone want to import Foo from within Foo.py itself. Should be from Bar.py, I guess. – bhaskarc Oct 25 '15 at 20:08
  • `from dirFoo import Foo` to say `Foo.bla()`. If using `import dirFoo.Foo` one should use `dirFoo.Foo.bla()` - pretty ugly even without camel case. – Cees Timmerman Nov 01 '16 at 13:13
  • 1
    how do you Import Bar.py from Foo.py?? – lurscher Oct 27 '18 at 20:55
45

The easiest method is to use sys.path.append().

However, you may be also interested in the imp module. It provides access to internal import functions.

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file 

This can be used to load modules dynamically when you don't know a module's name.

I've used this in the past to create a plugin type interface to an application, where the user would write a script with application specific functions, and just drop thier script in a specific directory.

Also, these functions may be useful:

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)
monkut
  • 36,357
  • 21
  • 109
  • 140
  • Note that in the documentation imp.load_source and imp.load_compiled are listed as obsolete. imp.find_module and imp.load_module are recommended instead. – amicitas Oct 18 '11 at 06:39
  • @amicitas, Can you please provide any reference for that(I need it, and I am using python 2.6. I am aware what 2.7 docs say about these, but couldn't find any reference regarding 2.6) – 0xc0de Aug 06 '12 at 06:46
  • @0xc0de You can find that statement in the docs for the imp module for both [python 2.7.3](http://docs.python.org/release/2.7.3/library/imp.html) and [python 2.6.7](http://docs.python.org/release/2.6.7/library/imp.html). It looks like those functions are not even in the docs for python 3.2. – amicitas Aug 07 '12 at 21:02
  • 1
    For importing source files like this in python 3.3, see [Import abitrary python source file. (Python 3.3+) - Stack Overflow](http://stackoverflow.com/questions/19009932/import-abitrary-python-source-file-python-3-3). Thanks, folks for the tips here. – nealmcb Oct 04 '14 at 16:34
44

This is the relevant PEP:

http://www.python.org/dev/peps/pep-0328/

In particular, presuming dirFoo is a directory up from dirBar...

In dirFoo\Foo.py:

from ..dirBar import Bar
Peter Crabtree
  • 903
  • 6
  • 5
23

The easiest way without any modification to your script is to set PYTHONPATH environment variable. Because sys.path is initialized from these locations:

  1. The directory containing the input script (or the current directory).
  2. PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  3. The installation-dependent default.

Just run:

export PYTHONPATH=/absolute/path/to/your/module

You sys.path will contains above path, as show below:

print sys.path

['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
James Gan
  • 6,064
  • 2
  • 24
  • 32
13

In my opinion the best choice is to put __ init __.py in the folder and call the file with

from dirBar.Bar import *

It is not recommended to use sys.path.append() because something might gone wrong if you use the same file name as the existing python package. I haven't test that but that will be ambiguous.

jhana
  • 131
  • 1
  • 2
  • weird that `from dirBar.Bar import *` works, but not `from dirBar.Bar import Bar`. do you know why * works? what if I had multiple files in dirBar/ and wanted to grab only a few of them (using a method like the one you've posted here)? – tester Jun 24 '11 at 07:33
  • 2
    @tester: Use `from dirBar import Bar`. – Brent Bradburn Dec 20 '12 at 03:38
  • @tester it's because the `from` indicates the source, and everything after `import` is what to grab from that source. `from dirBar.Bar import Bar` means "From source, import the source itself", which doesn't make sense. the `*` though means, "give me everything from source" – FuriousFolder Aug 02 '17 at 16:11
12

The quick-and-dirty way for Linux users

If you are just tinkering around and don't care about deployment issues, you can use a symbolic link (assuming your filesystem supports it) to make the module or package directly visible in the folder of the requesting module.

ln -s (path)/module_name.py

or

ln -s (path)/package_name

Note: A "module" is any file with a .py extension and a "package" is any folder that contains the file __init__.py (which can be an empty file). From a usage standpoint, modules and packages are identical -- both expose their contained "definitions and statements" as requested via the import command.

See: http://docs.python.org/2/tutorial/modules.html

Brent Bradburn
  • 40,766
  • 12
  • 126
  • 136
10

For this case to import Bar.py into Foo.py, first I'd turn these folders into Python packages like so:

dirFoo\
    __init__.py
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Then I would do it like this in Foo.py:

from .dirBar import Bar

If I wanted the namespacing to look like Bar.whatever, or

from . import dirBar

If I wanted the namespacing dirBar.Bar.whatever. This second case is useful if you have more modules under the dirBar package.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Al Conrad
  • 1,180
  • 14
  • 11
10
from .dirBar import Bar

instead of:

from dirBar import Bar

just in case there could be another dirBar installed and confuse a foo.py reader.

jgomo3
  • 1,051
  • 10
  • 24
  • 2
    I was not able to do this on windows. Is this on Linux? – Gabriel Jun 15 '13 at 23:56
  • 1
    It will work from a script importing Foo. i.e: main.py imports dirFoo.Foo. If you are trying to run Foo.py as an script, it will Fail. See http://stackoverflow.com/questions/72852/how-to-do-relative-imports-in-python – jgomo3 Jun 17 '13 at 19:23
7

Add an __init__.py file:

dirFoo\
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Then add this code to the start of Foo.py:

import sys
sys.path.append('dirBar')
import Bar
Frederick The Fool
  • 31,355
  • 20
  • 78
  • 112
Josh
  • 71
  • 1
  • 1
  • 5
    If `dirBar` is already a Python package (by the existence of `dirBar/__init__.py`), there is no need to append `dirBar` to `sys.path`, no? The statement `import Bar` from `Foo.py` should suffice. – Santa Apr 18 '10 at 23:06
5

Relative sys.path example:

# /lib/my_module.py
# /src/test.py


if __name__ == '__main__' and __package__ is None:
    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
import my_module

Based on this answer.

Community
  • 1
  • 1
Der_Meister
  • 4,413
  • 2
  • 38
  • 47
5

Well, as you mention, usually you want to have access to a folder with your modules relative to where your main script is run, so you just import them.

Solution:

I have the script in D:/Books/MyBooks.py and some modules (like oldies.py). I need to import from subdirectory D:/Books/includes:

import sys,site
site.addsitedir(sys.path[0] + '\\includes')
print (sys.path)  # Just verify it is there
import oldies

Place a print('done') in oldies.py, so you verify everything is going OK. This way always works because by the Python definition sys.path as initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter.

If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Avenida Gez
  • 401
  • 5
  • 5
  • 1
    I had to use one forward slash instead of two backslashes (i.e. `site.addsitedir(sys.path[0]+'/includes')`) in my first simple Python program break_time.py: [https://github.com/ltfschoen/PythonTest](https://github.com/ltfschoen/PythonTest). I use system: MacOS v10.11.5, Python 2.7.12, IDLE IDE 2.7.12, Tk 8.5.9 – Luke Schoen Oct 30 '16 at 07:05
4

Simply you can use: from Desktop.filename import something

Example:

given that the file is name test.py in directory Users/user/Desktop , and will import everthing.

the code:

from Desktop.test import *

But make sure you make an empty file called "__init__.py" in that directory

0x1996
  • 71
  • 5
  • 1
    starred imports are advised against. see: https://stackoverflow.com/questions/2386714/why-is-import-bad – axolotl Jun 18 '18 at 17:54
  • i know thats why i firstly wrote `import something` then i said to make it easier `*` basically its not good for ram and also if 2 functions has the same name it will mass up your code – 0x1996 Jul 07 '18 at 10:24
3

Another solution would be to install the py-require package and then use the following in Foo.py

import require
Bar = require('./dirBar/Bar')
Niklas R
  • 14,369
  • 23
  • 82
  • 179
  • The URL actually seems to be https://pypi.org/project/require.py/, and note that it needs to be installed via Pip. – Flash Sheridan Nov 09 '18 at 21:39
  • 1
    @FlashSheridan Nope, that's a different project. I deleted py-require as I was certain no one was using it, I did not think of this post though. If you still need a `require()` function, you can take a look at my Node.py project: https://github.com/nodepy/nodepy – Niklas R Nov 12 '18 at 20:48
2

Here's a way to import a file from one level above, using the relative path.

Basically, just move the working directory up a level (or any relative location), add that to your path, then move the working directory back where it started.

#to import from one level above:
cwd = os.getcwd()
os.chdir("..")
below_path =  os.getcwd()
sys.path.append(below_path)
os.chdir(cwd)
Justin Muller
  • 706
  • 5
  • 4
0

I'm not experienced about python, so if there is any wrong in my words, just tell me. If your file hierarchy arranged like this:

project\
    module_1.py 
    module_2.py

module_1.py defines a function called func_1(), module_2.py:

from module_1 import func_1

def func_2():
    func_1()

if __name__ == '__main__':
    func_2()

and you run python module_2.py in cmd, it will do run what func_1() defines. That's usually how we import same hierarchy files. But when you write from .module_1 import func_1 in module_2.py, python interpreter will say No module named '__main__.module_1'; '__main__' is not a package. So to fix this, we just keep the change we just make, and move both of the module to a package, and make a third module as a caller to run module_2.py.

project\
    package_1\
        module_1.py
        module_2.py
    main.py

main.py:

from package_1.module_2 import func_2

def func_3():
    func_2()

if __name__ == '__main__':
    func_3()

But the reason we add a . before module_1 in module_2.py is that if we don't do that and run main.py, python interpreter will say No module named 'module_1', that's a little tricky, module_1.py is right beside module_2.py. Now I let func_1() in module_1.py do something:

def func_1():
    print(__name__)

that __name__ records who calls func_1. Now we keep the . before module_1 , run main.py, it will print package_1.module_1, not module_1. It indicates that the one who calls func_1() is at the same hierarchy as main.py, the . imply that module_1 is at the same hierarchy as module_2.py itself. So if there isn't a dot, main.py will recognize module_1 at the same hierarchy as itself, it can recognize package_1, but not what "under" it.

Now let's make it a bit complicated. You have a config.ini and a module defines a function to read it at the same hierarchy as 'main.py'.

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
    main.py

And for some unavoidable reason, you have to call it with module_2.py, so it has to import from upper hierarchy.module_2.py:

 import ..config
 pass

Two dots means import from upper hierarchy (three dots access upper than upper,and so on). Now we run main.py, the interpreter will say:ValueError:attempted relative import beyond top-level package. The "top-level package" at here is main.py. Just because config.py is beside main.py, they are at same hierarchy, config.py isn't "under" main.py, or it isn't "leaded" by main.py, so it is beyond main.py. To fix this, the simplest way is:

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
main.py

I think that is coincide with the principle of arrange project file hierarchy, you should arrange modules with different function in different folders, and just leave a top caller in the outside, and you can import how ever you want.

-4

This also works, and is much simpler than anything with the sys module:

with open("C:/yourpath/foobar.py") as f:
    eval(f.read())
jgilley
  • 11
  • 1
    If OP was going to hardcode a path, they could just insert that path into the PYTHONPATH anyway. I think the point is doing so in a manner that does not hardcode a path since it would break anywhere else. – Matthew Sep 26 '18 at 20:56
-15

Call me overly cautious, but I like to make mine more portable because it's unsafe to assume that files will always be in the same place on every computer. Personally I have the code look up the file path first. I use Linux so mine would look like this:

import os, sys
from subprocess import Popen, PIPE
try:
    path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines()[0]
    if not sys.path.__contains__(path):
        sys.path.append(path)
except IndexError:
    raise RuntimeError("You must have FILE to run this program!")

That is of course unless you plan to package these together. But if that's the case you don't really need two separate files anyway.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123