34

So there are a lot of pretty similar questions but none of the answers seems to satisfy what I'm looking for.

Essentially I am running a python script using an absolute directory in the command line.
Within this file itself, I want to import a module/file,I currently use an absolute path to do this (sys.path.append(/....).
But I would like to use a relative path, relative to the script itself.
All I seem to be able to do is append a path relative to my present working directory.

How do I do this?

Pratik Singhal
  • 6,283
  • 10
  • 55
  • 97
user2564502
  • 937
  • 2
  • 10
  • 16
  • Can you give an example of what you want to import? – finiteautomata Jan 21 '14 at 13:21
  • BTW, I think you should read documentation on packages http://docs.python.org/2/tutorial/modules.html#packages – finiteautomata Jan 21 '14 at 13:25
  • And this may also help you http://as.ynchrono.us/2007/12/filesystem-structure-of-python-project_21.html . I have had the same problem as you when I first came to python. – finiteautomata Jan 21 '14 at 13:30
  • 1
    Hi, it's just a python file from a directory above where my script is. Am I really using packages? Currently at the top of my file, it says 'sys.path.append("/directory/file") I would like to just put something like 'sys.path.append("../file") But that just appends something relative to the pwd I am running the script from (I run it using '/directory1/director2/file.py') – user2564502 Jan 21 '14 at 13:55
  • Don't. Expand the relative path to an absolute path, and append that. – David Heffernan Jan 21 '14 at 14:12
  • Well, perhaps for a quick and dirty script it may work @user2564502, but consider it is not a clean solution doing such thing in a bigger project. – finiteautomata Jan 21 '14 at 14:30
  • Hi, sorry David, what do you mean by that? I know the file's absolute path - are you saying that I should use that? – user2564502 Jan 22 '14 at 15:59
  • Normally, `sys.path` is modified by **pre**pending a path, because the purpose is to override what *would already* be found - so something needs to come before that in the search order. However, `sys.path` hacks are rarely if ever necessary. Many major Python code projects, spanning hundreds of thousands of lines of code each, get by just fine without them. – Karl Knechtel Jan 13 '23 at 02:44

1 Answers1

70

The two below alternate possibilities apply to both Python versions 2 and 3. Choose the way you prefer. All use cases are covered.

Example 1

main script:      /some/path/foo/foo.py
module to import: /some/path/foo/bar/sub/dir/mymodule.py

Add in foo.py

import sys, os
sys.path.append(os.path.join(sys.path[0],'bar','sub','dir'))
from mymodule import MyModule

Example 2

main script:      /some/path/work/foo/foo.py
module to import: /some/path/work/bar/mymodule.py

Add in foo.py

import sys, os
sys.path.append(os.path.join(os.path.dirname(sys.path[0]),'bar'))
from mymodule import MyModule

Explanations

  • sys.path[0] is /some/path/foo in both examples
  • os.path.join('a','b','c') is more portable than 'a/b/c'
  • os.path.dirname(mydir) is more portable than os.path.join(mydir,'..')

See also

Documentation about importing modules:

oHo
  • 51,447
  • 27
  • 165
  • 200