2

I am trying to get the file name and directory of the currently executing script and this is the code that works:

import inspect, os
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))

In php this is just echo dirname(__FILE__). Nice and simple.

There are suggestions that dirname(__file__) should work in Python but it returns an empty string when running via the command line.

My question is that why do I have to write all of this code to get the filename:

print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))

and am I doing it wrong?

3 Answers 3

4

The __file__ value for the current script is the exact same path you passed to Python; python yourscript.py is thus a relative path and doesn't include the directory name. You do need to make it an absolute path, but you do not need to use inspect:

import os.path

print os.path.dirname(os.path.abspath(__file__))

Demo:

$ cat /private/tmp/test.py 
import os.path

print os.path.dirname(os.path.abspath(__file__))

$ python /private/tmp/test.py 
/private/tmp
$ cd /private/tmp/
$ python test.py 
/private/tmp

In PHP, you have the luxury of the web server executing your files with fully specified absolute paths, so you never saw this 'problem' crop up there.

Sign up to request clarification or add additional context in comments.

4 Comments

__file__ does not work in the __main__ module.. if you use the python shell.
@User: Have you tried it? It works just fine. We are not testing against __name__, we are using __file__, which for the main script is the exact path passed to Python.
Yes i tried this in a simple script. Not using the interactive shell. Simply in main.py.
@MartyWallace: I never said you were using the interactive shell. My demonstration above is done entirely in Bash. Did you try my version?
1

My question is that why do i have to write all of this code to get the filename:

print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))

Let's take it piece by piece.

First, the print is 1 character longer than PHP's echo. I doubt you have a problem with that.

Next, you have to use os.path.dirname instead of just dirname because Python allows code to be organized into modules, and allows you to reference things by qualified name. This is why Python can have functions like gzip.open and io.open that have the same name. But it doesn't force you to use qualified names if you don't want to; if you'd done, say, from os.path import dirname instead of import os, you could just use dirname.

Next, you need the abspath because you may have a relative path. This is actually exactly the same as in PHP. It's just that you're used to running PHP from a web browser setup that always runs your scripts by absolute path. You can do the same in Python if you want.

Finally:

There are suggestions that dirname(__file__) should work in python but it returns an empty string when running via the command line.

Not true.

$ cat > test.py
print __file___
$ python test.py
test.py

If by "running via the command line" you meant "using the interactive interpreter", of course, there is no __file__, because there is no file (except the terminal stdin).

Or, if you're printing the dirname of a relative path like test.py, of course that's always going to be an empty string, just as it would be in PHP.

Putting it all together:

$ cat > test.py
from os.path import dirname
print dirname(__file__)
$ python $(abspath test.py)
/Users/abarnert/src/test

Just like PHP.

2 Comments

I was not using the interactive shell. I simply have a script main.py
@MartyWallace: It's very hard to guess what you're doing wrong with minimal information, but my first guess would be exactly what I explained in the very next sentence after the one you replied to: You're running python main.py, so __file__ is the relative path 'main.py', so dirname(__file__) is ''. And I'm guessing you didn't bother to look at __file__; you just saw that dirname(__file__) was empty, and assumed that "__file__ doesn't work because Python sucks."
0

In case __file__ is not set, you can get the directory via

import sys, os
script = os.path.abspath(sys.argv[0] or 'unknown script')
directory = os.path.dirname(script))

6 Comments

That will not give you the absolute path of the file. Just the script name!
os.path.abspath() will use os.getcwd() as needed; and sys.argv[0] is always set.
sys.argv[0] is not set in case i use the IDLE without executing a script.
@User: IDLE is not a normal environment; you are running an interactive interpreter then.
@User: Well, if you're not executing a script, you don't have a script to get the name of…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.