1

So I've just coded this class for a title screen and it works well. However, one of the people I'm working with on the project mentioned that I shouldn't use:

os.chdir(os.getcwd() + "/..")

resource = (os.getcwd() + "/media/file name")

to get to the super directory. He did mention something about the pythonpath though. We're using Eclipse if this is of some help.

For more context we're making a multi-platform game so we can't just synchronize our directories and hard-code it (although we are using git so the working directory is synchronized). Basically, I need some way to get from a script file in a "src' folder to a "media" folder that's next to it (AKA There's a super (project) folder with both "src" and "media" folders in it).

Any help would be greatly appreciated, but please don't say "google it" because I tried that before coming here (I don't know if that's a frequent thing here, but I've seen it too many times elsewhere...when I've googled for answers, sorry if I sound jerkish for saying that)

  • I don't see it. I see how my current solution is similar, but that's just the problem. There's a way to do this, that's better than the way that I'm doing it. – ElectricErger Mar 05 '13 at 06:08
  • I think that the question is not so much about getting to the parent directory than to move to a directory *relative to the script/program*, as the title indicates. So, I think that this question is not a duplicate of http://stackoverflow.com/q/2860153/42973. – Eric O. Lebigot Mar 05 '13 at 11:45

3 Answers3

2

Python programs do have the concept of a current working directory, which is generally the directory from which the script was run. This is "where they look for files" with a relative path.

However, since your program can be run from a different folder than the one it is in, your directory of reference needs to instead refer to the directory your script is in (the current directory is not related to the location of your script, in general). The directory where your script is found is obtained with

script_dir = os.path.dirname(__file__)

Note that this path can be relative (possibly empty), so it is still important that the current working directory of your script be the same as the directory when your script was read by the python interpreter (which is when __file__ is set). It is important to convert the possibly relative script_dir into an absolute path if the current working directory is changed later in the code:

# If script_dir is relative, the current working directory is used, here. This is correct if the current
# working directory is the same as when the script was read by the Python interpreter (which is
# when __file__ was set):
script_dir = os.path.abspath(script_dir)

You can then get to the directory media in the parent directory with the platform-independent

os.path.join(script_dir, os.path.pardir, 'media')

In fact os.path.pardir (or equivalently os.pardir) is the platform-independent parent directory convention, and os.path.join() simply joins paths in a platform independent way.

Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
1

I'd recommend something like:

import os.path

base_folder = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
media_folder = os.path.join(base_folder, "media")
src_folder = os.path.join(base_folder, "src")

resource = os.path.join(media_folder, "filename")

for path in [base_folder, media_folder, src_folder, resource]:
    print path

The main ingredients are:

  • __file__: gets the path to the current source file (unlike sys.argv[0], which gives the path the script that was called)
  • os.path.split(): splits a path into the relative file/folder name and the base folder containing it. Using it twice as in base_folder = ... will give the parent directory.
  • os.path.join: OS-independent and correct combination of path names. Is aware of missing or multiple /s or \s
Thorsten Kranz
  • 12,492
  • 2
  • 39
  • 56
  • -1 because it depends on how the python file is called. `os.path.split(__file__)[0]` can be empty in some cases, breaking things. Also there are already built-in ways of doing this (namely `os.path.dirname`), so prefer to use those than mucking around with `split` – wim Mar 05 '13 at 06:28
  • 1
    `dirname` is what I meant to use, for sure. Fixed answer to reflect this. The main point of my answer is the usage of `__file__` which wasn't mentioned by the earlier answer. – Thorsten Kranz Mar 05 '13 at 07:28
  • 2
    +1 because you are right: `__file__` is the best reference directory, since the `media` folder is placed relative to the script, not relative to where users run it (i.e. the current directory is indeed not as relevant). – Eric O. Lebigot Mar 05 '13 at 08:10
0

Consider using os.path.dirname() and os.path.join(). These should work in a platform independent way.

Jim Garrison
  • 4,199
  • 4
  • 25
  • 39
  • Don't I need a path for so.path.dirname(), and isn't that platform dependent? – ElectricErger Mar 05 '13 at 06:12
  • 1
    Yes, you do - use `os.path.dirname(os.path.abspath(__file__))` – wim Mar 05 '13 at 06:28
  • @JimGarrison: This will not work if the script is not run from the directory it is in. This is probably one of the reasons why some people mentioned that the code in the question "should not be used" (not to mention the fact that some other parts of the code might change the current working directory). – Eric O. Lebigot Mar 05 '13 at 08:01