how to get script name when using execfile() in IPython to run script

I have scripts calling other script files but I need to get the filepath of the file that is currently running within the process.

For example, let's say I have three files. Using execfile:

  • script_1.py calls script_2.py.
  • In turn, script_2.py calls script_3.py.

How can I get the file name and path of script_3.py, from code within script_3.py, without having to pass that information as arguments from script_2.py?

(Executing os.getcwd() returns the original starting script's filepath not the current file's.)

Replay

p1.py:

execfile("p2.py")

p2.py:

import inspect, os
print inspect.getfile(inspect.currentframe()) # script filename (usually with path)
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory

__file__

as others have said. You may want to use:

os.path.realpath(__file__)

The suggestions marked as best are all true if your script consists of only one file.

If you want to find out the name of the executable (i.e. the root file passed to the python interpreter for the current program) from a file that may be imported as a module, you need to do this (let's assume this is in a file named foo.py):

import inspect

print inspect.stack()[-1][1]

Because the last thing ([-1]) on the stack is the first thing that went into it (stacks are LIFO/FILO data structures).

Then in file bar.py if you import foo it'll print bar.py, rather than foo.py, which would be the value of all of these:

  • __file__
  • inspect.getfile(inspect.currentframe())
  • inspect.stack()[0][1]

I think this is cleaner:

import inspect
print inspect.stack()[0][1]

and gets the same information as:

print inspect.getfile(inspect.currentframe())

Where [0] is the current frame in the stack (top of stack) and [1] is for the file name, increase to go backwards in the stack i.e.

print inspect.stack()[1][1]

would be the file name of the script that called the current frame. Also, using [-1] will get you to the bottom of the stack, the original calling script.

import os
print os.path.basename(__file__)

this will give us the filename only. i.e. if abspath of file is c:\abcd\abc.py then 2nd line will print abc.py

It's not entirely clear what you mean by "the filepath of the file that is currently running within the process". sys.argv[0] usually contains the location of the script that was invoked by the Python interpreter. Check the sys documentation for more details.

As @Tim and @Pat Notz have pointed out, the __file__ attribute provides access to

the file from which the module was loaded, if it was loaded from a file

import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only

Here is an experiment based on the answers in this thread - with Python 2.7.10 on Windows.

The stack-based ones are the only ones that seem to give reliable results. The last two have the shortest syntax, ie -

print os.path.abspath(inspect.stack()[0][1])                   # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\testpath\lib

Here's to these being added to sys as functions! Credit to @Usagi and @pablog

Based on the following three files, and running script1.py from its folder with python script1.py (also tried execfiles with absolute paths and calling from a separate folder).

C:\testpath\script1.py: execfile('script2.py')
C:\testpath\script2.py: execfile('lib/script3.py')
C:\testpath\lib\script3.py:

import sys
import os
import inspect

print "Python " + sys.version
print

print __file__                                        # script1.py
print sys.argv[0]                                     # script1.py
print inspect.stack()[0][1]                           # lib/script3.py
print sys.path[0]                                     # C:\testpath
print

print os.path.realpath(__file__)                      # C:\testpath\script1.py
print os.path.abspath(__file__)                       # C:\testpath\script1.py
print os.path.basename(__file__)                      # script1.py
print os.path.basename(os.path.realpath(sys.argv[0])) # script1.py
print

print sys.path[0]                                     # C:\testpath
print os.path.abspath(os.path.split(sys.argv[0])[0])  # C:\testpath
print os.path.dirname(os.path.abspath(__file__))      # C:\testpath
print os.path.dirname(os.path.realpath(sys.argv[0]))  # C:\testpath
print os.path.dirname(__file__)                       # (empty string)
print

print inspect.getfile(inspect.currentframe())         # lib/script3.py

print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\testpath\lib
print

print os.path.abspath(inspect.stack()[0][1])          # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\testpath\lib
print

The __file__ attribute works for both the file containing the main execution code as well as imported modules.

See https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__

import sys

print sys.path[0]

this would print the path of the currently executing script

import sys
print sys.argv[0]

I think it's just __file__ Sounds like you may also want to checkout the inspect module.

I have a script that must work under windows environment. This code snipped is what I've finished with:

import os,sys
PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])

it's quite a hacky decision. But it requires no external libraries and it's the most important thing in my case.

You can use inspect.stack()

import inspect,os
inspect.stack()[0]  => (<frame object at 0x00AC2AC0>, 'g:\\Python\\Test\\_GetCurrentProgram.py', 15, '<module>', ['print inspect.stack()[0]\n'], 0)
os.path.abspath (inspect.stack()[0][1]) => 'g:\\Python\\Test\\_GetCurrentProgram.py'

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

No need for inspect or any other library.

This worked for me when I had to import a script (from a different directory then the executed script), that used a configuration file residing in the same folder as the imported script.

This should work:

import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))

import os

import wx

# return the full path of this file
print(os.getcwd())

icon = wx.Icon(os.getcwd() + '/img/image.png', wx.BITMAP_TYPE_PNG, 16, 16)

# put the icon on the frame
self.SetIcon(icon)

I used the approach with __file__
os.path.abspath(__file__)
but there is a little trick, it returns the .py file when the code is run the first time, next runs give the name of *.pyc file
so I stayed with:
inspect.getfile(inspect.currentframe())
or
sys._getframe().f_code.co_filename

if you want just the filename without ./ or .py you can try this

filename = testscript.py
file_name = __file__[2:-3]

file_name will print testscript you can generate whatever you want by changing the index inside []

Category: python Time: 2008-09-08 Views: 3

Related post

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development

search

Front-end development

Database

development tools

Open Platform

Javascript development

.NET development

cloud computing

server

Copyright (C) avrocks.com, All Rights Reserved.

processed in 0.210 (s). 12 q(s)