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 stackoverflow.com/questions/279237/…
–
sorinMay 26 '11 at 6:17

I had a similar problem and I found this and it works!! apt-get install python-profiler
–
ldcl289Sep 22 '11 at 20:18

Just in case somebody wants to do it statically and gets here (like I did :) you can also set up the PYTHONPATH environment variable
–
okaramJan 10 at 21:23

18 Answers
18

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 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. Probably it fails too. Add a comment if you really need a better solution, I may invest few more hours in improving it.

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
–
delinquentmeJan 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 LewisJan 17 '12 at 5: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.
–
mhilsJul 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!
–
sorinJul 13 '12 at 12:32

6

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())))
–
tedAug 14 '12 at 7:37

Note that this file can be completely empty.
–
Harley HolcombeNov 10 '08 at 22:00

20

If dirBar's parent directory is not in sys.path then the presence of __init__.py in the dirBar directory doesn't help much.
–
J.F. SebastianNov 10 '08 at 22:40

1

The above comment assumes that dirBar is a sub-package.
–
J.F. SebastianNov 10 '08 at 23:11

1

-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 TomczakNov 22 '11 at 23:27

8

"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.LottNov 23 '11 at 0:47

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.
–
nobarDec 20 '12 at 1:11

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.

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 LeysNov 10 '08 at 22:00

1

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 MDec 31 '12 at 8:59

I have tried the same thing and fail. I do not know why. ImportError: No module named customMath
–
Zhang MengMar 5 '14 at 12:09

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.

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.
–
amicitasOct 18 '11 at 6: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)
–
0xc0deAug 6 '12 at 6:46

@0xc0de You can find that statement in the docs for the imp module for both python 2.7.3 and python 2.6.7. It looks like those functions are not even in the docs for python 3.2.
–
amicitasAug 7 '12 at 21:02

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)?
–
testerJun 24 '11 at 7:33

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.

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.
–
SantaApr 18 '10 at 23:06

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: