Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

This question already has an answer here:

Consider the following Python code:

import os
print os.getcwd()

I use os.getcwd() to get the script file's directory location. When I run the script from the command line it gives me the correct path whereas when I run it from a script run by code in a Django view it prints /.

How can I get the path to the script from within a script run by a Django view?

UPDATE:
Summing up the answers thus far - os.getcwd() and os.path.abspath() both give the current working directory which may or may not be the directory where the script resides. In my web host setup __file__ gives only the filename without the path.

Isn't there any way in Python to (always) be able to receive the path in which the script resides?

share|improve this question

marked as duplicate by J.F. Sebastian python May 11 at 21:24

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
You should read that linked article more closely. It never suggests using getcwd will tell you your script's location. It suggests argv[0], dirname, and abspath. – Rob Kennedy Feb 8 '11 at 15:27
    
@Rob - "print sys.argv[0]" on my web host only gives the filename, without the path – Jonathan Feb 8 '11 at 15:57
    
@Rob - here's an excerpt from the linked article "os.getcwd() returns the current working directory." – Jonathan Feb 8 '11 at 19:08
5  
Yes, but the current working directory has absolutely no relation to the directory your script lives in. Compare with os.chdir, which sets the current working directory; it does not move your script file to a new location on the hard drive. The initial working directory might be the same as the directory your script lives in, but not always; the article even demonstrates that. – Rob Kennedy Feb 8 '11 at 20:12
1  
Note that __file__ will return the filename of the scripts context. Caveat emptor if you're calling out to an external script from your __main__ - you might get a different response than you expected. – tristan Oct 15 '12 at 16:22

12 Answers 12

up vote 353 down vote accepted

You need to call os.path.realpath on __file__, so that when __file__ is a filename without the path you still get the dir path:

import os
print os.path.dirname(os.path.realpath(__file__))
share|improve this answer
21  
This won't work if you're running from inside an interpreter, since you'll get NameError: name '__file__' is not defined – Ehtesh Choudhury Feb 26 '14 at 21:01
1  
Try running python -c 'import os; print os.path.dirname(os.path.realpath(__file__))', which is a set of commands run by a python interpreter. – Ehtesh Choudhury Jan 5 '15 at 19:50
20  
I think that is expected behaviour as, that python command does not exist within a file but inside a string which you pass to the interpreter – Har Apr 14 '15 at 8:15
2  
@EhteshChoudhury That's because __file__ is a module variable that is only created when a script is being executed -> This variable represents the location of the script. An interpreter isn't being run from a file, so it can't have such a variable. – Zizouz212 Jan 21 at 2:52
1  
Mike, how is it wrong? os.path.dirname(os.path.realpath(__file__)) == sys.path[0] They're identical. – bobpaul Apr 22 at 16:51

I use :

def getScriptPath():
    return os.path.dirname(os.path.realpath(sys.argv[0]))

As aiham points out in a comment, you can define this function in a module an use it in different scripts.

my2c

share|improve this answer
5  
+1 because the useful __file__ module attribute is not always defined. – iacopo Jul 3 '13 at 12:13
3  
This is also useful if you want to place getScriptPath() in a different module but get the path of the file that was actually executed rather than the module path. – aiham Sep 18 '14 at 1:13
    
@aiham: Good point. In fact this function is in my framework utils module :) – neuro Sep 18 '14 at 7:20
    
@aiham: This does not seem to work for me when using a virtualenv. I get the path to the virtualenv's bin dir instead of the .py file where I call getScriptPath(). i.e. /home/vagrant/.virtualenvs/myvenv/bin/ ...Any idea around that? – MJ Davis Oct 9 '15 at 2:22
    
Hum look at sys.argv[1:] ... – neuro Oct 9 '15 at 14:47

Try sys.path[0].

To quote from the Python docs:

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.

share|improve this answer
5  
+1 for citing docs – Sunny Patel May 20 '14 at 1:51
    
this is usually the correct solution – vidstige Dec 1 '15 at 9:25
    
This is the correct solution. – Mike Apr 18 at 4:46

This code:

import os
dn = os.path.dirname(os.path.realpath(__file__))

sets "dn" to the name of the directory containing the currently executing script. This code:

fn = os.path.join(dn,"vcb.init")
fp = open(fn,"r")

sets "fn" to "script_dir/vcb.init" (in a platform independent manner) and opens that file for reading by the currently executing script.

Note that "the currently executing script" is somewhat ambiguous. If your whole program consists of 1 script, then that's the currently executing script and the "sys.path[0]" solution works fine. But if your app consists of script A, which imports some package "P" and then calls script "B", then "P.B" is currently executing. If you need to get the directory containing "P.B", you want the "os.path.realpath(__file__)" solution.

"__file__" just gives the name of the currently executing (top-of-stack) script: "x.py". It doesn't give any path info. It's the "os.path.realpath" call that does the real work.

share|improve this answer
import os,sys
# Store current working directory
pwd = os.path.dirname(__file__)
# Append current directory to the python path
sys.path.append(pwd)
share|improve this answer
    
This works great on my dev machine but doesn't work on my web host - I get '/' – Jonathan Feb 10 '11 at 7:21
    
Odd, do you have access to the apache conf files? Or is this a windows server? – jbcurtin Feb 10 '11 at 10:02
import os
script_dir = os.path.dirname(os.path.realpath(__file__)) + os.sep
share|improve this answer
    
Thanks, I needed the os.sep :D – Broken_Window Oct 31 '15 at 16:33

Use os.path.abspath('')

share|improve this answer
    
This works for everything on my dev machine, but only for script files on my web host. It does not work for settings.py, e.g. the following doesn't work: TEMPLATE_DIRS = ((os.path.abspath('')+'/templates'),) – Jonathan Feb 8 '11 at 19:14

This worked for me (and I found it via the other stackoverflow quetsion below)

os.path.realpath(__file__)

Retrieving python module path

share|improve this answer

Here's what I ended up with. This works for me if I import my script in the interpreter, and also if I execute it as a script:

import os
import sys

# Returns the directory the current script (or interpreter) is running in
def get_script_directory():
    path = os.path.realpath(sys.argv[0])
    if os.path.isdir(path):
        return path
    else:
        return os.path.dirname(path)
share|improve this answer

This is a pretty old thread but I've been having this problem when trying to save files into the current directory the script is in when running a python script from a cron job. getcwd() and a lot of the other path come up with your home directory.

to get an absolute path to the script i used

directory = os.path.abspath(os.path.dirname(__file__))

share|improve this answer
import os
exec_filepath = os.path.realpath(__file__)
exec_dirpath = exec_filepath[0:len(exec_filepath)-len(os.path.basename(__file__))]
share|improve this answer
    
Why not use os.path.dirname? – SpoonMeiser Jul 14 '13 at 20:13
    
I didn't know about os.path.dirname, maybe that works also. – Stan Jul 19 '13 at 6:09

Try this:

def get_script_path(for_file = None):
    path = os.path.dirname(os.path.realpath(sys.argv[0] or 'something'))
    return path if not for_file else os.path.join(path, for_file)
share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.