Understanding and testing [self._class_._module_]._file_ - python

When reading a python-based software, I feel confused about a line of python code: path = sys.modules[self.__class__.__module__].__file__.
I can guess it was trying to return the file name in class file, but I'm not very clear about the exact usage of this. I saved the related code segment into a file named test.py and I'm trying to test it by python test.py, but it does not print anything. How can I test this kind of file?
import os
import sys
class testloadfile:
def __init__(self, test_path=None):
if test_path is None:
path = sys.modules[self.__class__.__module__].__file__
# print path
path = os.path.abspath(os.path.join(path, os.pardir))
# print path
path = os.path.join(path, "test.r")
print(path)
test_path = path
print("r file loaded")

Classes in python have a __module__ attribute which contains the name of the module in which the class was defined. Additionally, each module contains a __file__ attribute which has the full path to the .py file.
He is trying to get the file path for the file in which the class was defined but he's not going the best way with doing it, ideally you could just index sys.modules by using __name__:
path = sys.modules[__name__].__file__
instead of going through the class (i.e self.__class__.__module__ == __name__). Do note here that if __name__ == "__main__" this will fail because the __main__ module does not have a __file__ attribute defined. You'll need to safeguard against it:
path = sys.modules[__name__].__file__ if __name__ == "__main__" else __file__
where if __name__ == "__main__" then __file__ will contain the path of the file being executed.
Next, add the usual clause in your script in order for it to initialize the object if the script is running as __main__:
if __name__ == "__main__":
testloadfile() # initialize
Now, if you call it as the __main__ script with:
python -m test.py
or if you import it, it will pickup the __file__ attribute, print it and then print the file name.
P.s: Fix the indentation in your final print.

Related

python import a module with source code in temporary file

import tempfile
tmp = tempfile.NamedTemporaryFile(delete=True)
try:
# do stuff with temp
tmp.write(b'def fun():\n\tprint("hello world!")\n')
if __name__ == '__main__':
func = __import__(tmp.name)
func.fun()
finally:
tmp.close() # deletes the file
So I want to create a temporary file, add some source code to it and then import the module and call the function, but I always run into this error:
ModuleNotFoundError: No module named '/var/folders/3w/yyp887lx4018h9s5sr0bwhkw0000gn/T/tmp84bk0bic'
It doesn't seem to find the module of the temporary file. How do I solve this?
There are a few problems with your code:
Your filename does not end with .py, but Python modules are expected to. You can fix this by setting suffix='.py' in NamedTemporaryFile().
__import__() is not the right way to load a module from a full path. See here: How to import a module given the full path?
You do not flush after writing and before importing, so even if Python does find the file, it may well be empty. Add tmp.flush() after writing to fix this.
Importing can only be done from certain directories which are part of the PYTHON_PATH. You can extend that. Then you will have to use __import__() with a module name (not a path in the file system). You will have to deal with the suffix for the temp file.
I implemented a simple version using the local directory for the temp module file and a version using a proper tempfile:
#!/usr/bin/env python3
import sys
import os
import tempfile
SCRIPT = '''\
def fun():
print("hello world!")
'''
# simple version using the local directory:
with open('bla.py', 'w') as tmp_module_file:
tmp_module_file.write(SCRIPT)
import bla
bla.fun()
# version using the tempfile module:
tmpfile = tempfile.NamedTemporaryFile(suffix='.py', delete=True)
try:
tmpfile.write(SCRIPT.encode('utf8'))
tmpfile.flush()
tmpmodule_path, tmpmodule_file_name = os.path.split(tmpfile.name)
tmpmodule_name = tmpmodule_file_name[:-3] # strip off the '.py'
sys.path.append(tmpmodule_path)
tmpmodule = __import__(tmpmodule_name)
finally:
tmpfile.close()
tmpmodule.fun()

Python: Dynamically importing a script in another folder from a string

I need to import and run a script from a string (path) which is located in another folder. The input needs to be completely dynamic. The code below works when the file is in the same folder but I can't seem to get it working when the file is located elsewhere.
main.py
path = 'bin\TestScript'
module = __import__(path)
my_class = getattr(module, '__main__')
instance = my_class(3,16)
print(instance)
TestScript.py
def __main__(a,b):
return(a*b)
Get the errror:
ImportError: No module named 'bin\\TestScript'
on windows os
You need to separate the directory from the module name and add that to the module search path. For example:
import os.path
import sys
path = 'bin\\TestScript'
mdir = os.path.dirname(path)
modname = os.path.basename(path)
sys.path.append(mdir)
module = __import__(modname)
my_class = getattr(module, '__main__')
instance = my_class(3,16)
print(instance)
An alternative is to make the directory "bin" a package.

Dynamic importing modules results in an ImportError

So I've been trying to make a simple program that will dynamically import modules in a folder with a certain name. I cd with os to the directory and I run module = __import__(module_name) as I'm in a for loop with all of the files names described being iterated into the variable module_name.
My only problem is I get hit with a:
ImportError: No module named "module_name"
(saying the name of the variable I've given as a string). The file exists, it's in the directory mentioned and import works fine in the same directory. But normal even import doesn't work for modules in the cd directory. The code looks as follows. I'm sorry if this is an obvious question.
import os
class Book():
def __init__(self):
self.name = "Book of Imps"
self.moduleNames = []
# configure path
def initialize(self):
path = os.getcwd() + '/Imp-pit'
os.chdir(path)
cwd = os.walk(os.getcwd())
x, y, z = next(cwd)
# Build Modules
for name in z:
if name[:3] == 'Imp':
module_name = name[:len(name) - 3]
module = __import__(module_name)
def start_sim():
s = Book()
s.initialize()
if __name__ == '__main__':
start_sim()
I don't think the interpreter dynamically alters sys.path if you simply change the current directory with os.chdir. You'll manually have to insert the path variable into the sys.path list for this to work, i.e:
sys.path.insert(0, path)
Python generally searches sys.path when looking for modules, so it will find it if you specify it there.
An additional note; don't use __import__, rather use importlib.import_module. The interface is exactly the same but the second is generally advised in the documentation.
You should use the try-except concept, e.g.:
try:
import csv
except ImportError:
raise ImportError('<error message>')
If I did understand you correct then
try:
module = __import__(module_name)
except ImportError:
raise ImportError('<error message>')

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

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.)
__file__
as others have said. You may also want to use os.path.realpath to eliminate symlinks:
import os
os.path.realpath(__file__)
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
Update 2018-11-28:
Here is a summary of experiments with Python 2 and 3. With
main.py - runs foo.py
foo.py - runs lib/bar.py
lib/bar.py - prints filepath expressions
| Python | Run statement | Filepath expression |
|--------+---------------------+----------------------------------------|
| 2 | execfile | os.path.abspath(inspect.stack()[0][1]) |
| 2 | from lib import bar | __file__ |
| 3 | exec | (wasn't able to obtain it) |
| 3 | import lib.bar | __file__ |
For Python 2, it might be clearer to switch to packages so can use from lib import bar - just add empty __init__.py files to the two folders.
For Python 3, execfile doesn't exist - the nearest alternative is exec(open(<filename>).read()), though this affects the stack frames. It's simplest to just use import foo and import lib.bar - no __init__.py files needed.
See also Difference between import and execfile
Original Answer:
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, i.e. -
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
Here's to these being added to sys as functions! Credit to #Usagi and #pablog
Based on the following three files, and running main.py from its folder with python main.py (also tried execfiles with absolute paths and calling from a separate folder).
C:\filepaths\main.py: execfile('foo.py')
C:\filepaths\foo.py: execfile('lib/bar.py')
C:\filepaths\lib\bar.py:
import sys
import os
import inspect
print "Python " + sys.version
print
print __file__ # main.py
print sys.argv[0] # main.py
print inspect.stack()[0][1] # lib/bar.py
print sys.path[0] # C:\filepaths
print
print os.path.realpath(__file__) # C:\filepaths\main.py
print os.path.abspath(__file__) # C:\filepaths\main.py
print os.path.basename(__file__) # main.py
print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
print
print sys.path[0] # C:\filepaths
print os.path.abspath(os.path.split(sys.argv[0])[0]) # C:\filepaths
print os.path.dirname(os.path.abspath(__file__)) # C:\filepaths
print os.path.dirname(os.path.realpath(sys.argv[0])) # C:\filepaths
print os.path.dirname(__file__) # (empty string)
print
print inspect.getfile(inspect.currentframe()) # lib/bar.py
print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
print
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
print
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
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only
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]
Since Python 3 is fairly mainstream, I wanted to include a pathlib answer, as I believe that it is probably now a better tool for accessing file and path information.
from pathlib import Path
current_file: Path = Path(__file__).resolve()
If you are seeking the directory of the current file, it is as easy as adding .parent to the Path() statement:
current_path: Path = Path(__file__).parent.resolve()
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
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
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.
Try this,
import os
os.path.dirname(os.path.realpath(__file__))
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.
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
I think it's just __file__ Sounds like you may also want to checkout the inspect module.
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 sys
print sys.argv[0]
print(__file__)
print(__import__("pathlib").Path(__file__).parent)
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]))
Here is what I use so I can throw my code anywhere without issue. __name__ is always defined, but __file__ is only defined when the code is run as a file (e.g. not in IDLE/iPython).
if '__file__' in globals():
self_name = globals()['__file__']
elif '__file__' in locals():
self_name = locals()['__file__']
else:
self_name = __name__
Alternatively, this can be written as:
self_name = globals().get('__file__', locals().get('__file__', __name__))
To get directory of executing script
print os.path.dirname( inspect.getfile(inspect.currentframe()))
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
I wrote a function which take into account eclipse debugger and unittest.
It return the folder of the first script you launch. You can optionally specify the __file__ var, but the main thing is that you don't have to share this variable across all your calling hierarchy.
Maybe you can handle others stack particular cases I didn't see, but for me it's ok.
import inspect, os
def getRootDirectory(_file_=None):
"""
Get the directory of the root execution file
Can help: http://stackoverflow.com/questions/50499/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing
For eclipse user with unittest or debugger, the function search for the correct folder in the stack
You can pass __file__ (with 4 underscores) if you want the caller directory
"""
# If we don't have the __file__ :
if _file_ is None:
# We get the last :
rootFile = inspect.stack()[-1][1]
folder = os.path.abspath(rootFile)
# If we use unittest :
if ("/pysrc" in folder) & ("org.python.pydev" in folder):
previous = None
# We search from left to right the case.py :
for el in inspect.stack():
currentFile = os.path.abspath(el[1])
if ("unittest/case.py" in currentFile) | ("org.python.pydev" in currentFile):
break
previous = currentFile
folder = previous
# We return the folder :
return os.path.dirname(folder)
else:
# We return the folder according to specified __file__ :
return os.path.dirname(os.path.realpath(_file_))
Simplest way is:
in script_1.py:
import subprocess
subprocess.call(['python3',<path_to_script_2.py>])
in script_2.py:
sys.argv[0]
P.S.: I've tried execfile, but since it reads script_2.py as a string, sys.argv[0] returned <string>.
The following returns the path where your current main script is located at. I tested this with Linux, Win10, IPython and Jupyter Lab. I needed a solution that works for local Jupyter notebooks as well.
import builtins
import os
import sys
def current_dir():
if "get_ipython" in globals() or "get_ipython" in dir(builtins):
# os.getcwd() is PROBABLY the dir that hosts the active notebook script.
# See also https://github.com/ipython/ipython/issues/10123
return os.getcwd()
else:
return os.path.abspath(os.path.dirname(sys.argv[0]))
Finding the home directory of the path in which your Python script resides
As an addendum to the other answers already here (and not answering the OP's question, since other answers already do that), if the path to your script is /home/gabriel/GS/dev/eRCaGuy_dotfiles/useful_scripts/cpu_logger.py, and you wish to obtain the home directory part of that path, which is /home/gabriel, you can do this:
import os
# Obtain the home dir of the user in whose home directory this script resides
script_path_list = os.path.normpath(__file__).split(os.sep)
home_dir = os.path.join("/", script_path_list[1], script_path_list[2])
To help make sense of this, here are the paths for __file__, script_path_list, and home_dir. Notice that script_path_list is a list of the path components, with the first element being an empty string since it originally contained the / root dir path separator for this Linux path:
__file__ = /home/gabriel/GS/dev/eRCaGuy_dotfiles/useful_scripts/cpu_logger.py
script_path_list = ['', 'home', 'gabriel', 'GS', 'dev', 'eRCaGuy_dotfiles', 'useful_scripts', 'cpu_logger.py']
home_dir = /home/gabriel
Source:
Python: obtain the path to the home directory of the user in whose directory the script being run is located [duplicate]

Python copy file from script directory to current directory [duplicate]

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.)
__file__
as others have said. You may also want to use os.path.realpath to eliminate symlinks:
import os
os.path.realpath(__file__)
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
Update 2018-11-28:
Here is a summary of experiments with Python 2 and 3. With
main.py - runs foo.py
foo.py - runs lib/bar.py
lib/bar.py - prints filepath expressions
| Python | Run statement | Filepath expression |
|--------+---------------------+----------------------------------------|
| 2 | execfile | os.path.abspath(inspect.stack()[0][1]) |
| 2 | from lib import bar | __file__ |
| 3 | exec | (wasn't able to obtain it) |
| 3 | import lib.bar | __file__ |
For Python 2, it might be clearer to switch to packages so can use from lib import bar - just add empty __init__.py files to the two folders.
For Python 3, execfile doesn't exist - the nearest alternative is exec(open(<filename>).read()), though this affects the stack frames. It's simplest to just use import foo and import lib.bar - no __init__.py files needed.
See also Difference between import and execfile
Original Answer:
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, i.e. -
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
Here's to these being added to sys as functions! Credit to #Usagi and #pablog
Based on the following three files, and running main.py from its folder with python main.py (also tried execfiles with absolute paths and calling from a separate folder).
C:\filepaths\main.py: execfile('foo.py')
C:\filepaths\foo.py: execfile('lib/bar.py')
C:\filepaths\lib\bar.py:
import sys
import os
import inspect
print "Python " + sys.version
print
print __file__ # main.py
print sys.argv[0] # main.py
print inspect.stack()[0][1] # lib/bar.py
print sys.path[0] # C:\filepaths
print
print os.path.realpath(__file__) # C:\filepaths\main.py
print os.path.abspath(__file__) # C:\filepaths\main.py
print os.path.basename(__file__) # main.py
print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
print
print sys.path[0] # C:\filepaths
print os.path.abspath(os.path.split(sys.argv[0])[0]) # C:\filepaths
print os.path.dirname(os.path.abspath(__file__)) # C:\filepaths
print os.path.dirname(os.path.realpath(sys.argv[0])) # C:\filepaths
print os.path.dirname(__file__) # (empty string)
print
print inspect.getfile(inspect.currentframe()) # lib/bar.py
print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
print
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
print
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
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only
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]
Since Python 3 is fairly mainstream, I wanted to include a pathlib answer, as I believe that it is probably now a better tool for accessing file and path information.
from pathlib import Path
current_file: Path = Path(__file__).resolve()
If you are seeking the directory of the current file, it is as easy as adding .parent to the Path() statement:
current_path: Path = Path(__file__).parent.resolve()
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
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
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.
Try this,
import os
os.path.dirname(os.path.realpath(__file__))
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.
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
I think it's just __file__ Sounds like you may also want to checkout the inspect module.
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 sys
print sys.argv[0]
print(__file__)
print(__import__("pathlib").Path(__file__).parent)
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]))
Here is what I use so I can throw my code anywhere without issue. __name__ is always defined, but __file__ is only defined when the code is run as a file (e.g. not in IDLE/iPython).
if '__file__' in globals():
self_name = globals()['__file__']
elif '__file__' in locals():
self_name = locals()['__file__']
else:
self_name = __name__
Alternatively, this can be written as:
self_name = globals().get('__file__', locals().get('__file__', __name__))
To get directory of executing script
print os.path.dirname( inspect.getfile(inspect.currentframe()))
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
I wrote a function which take into account eclipse debugger and unittest.
It return the folder of the first script you launch. You can optionally specify the __file__ var, but the main thing is that you don't have to share this variable across all your calling hierarchy.
Maybe you can handle others stack particular cases I didn't see, but for me it's ok.
import inspect, os
def getRootDirectory(_file_=None):
"""
Get the directory of the root execution file
Can help: http://stackoverflow.com/questions/50499/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing
For eclipse user with unittest or debugger, the function search for the correct folder in the stack
You can pass __file__ (with 4 underscores) if you want the caller directory
"""
# If we don't have the __file__ :
if _file_ is None:
# We get the last :
rootFile = inspect.stack()[-1][1]
folder = os.path.abspath(rootFile)
# If we use unittest :
if ("/pysrc" in folder) & ("org.python.pydev" in folder):
previous = None
# We search from left to right the case.py :
for el in inspect.stack():
currentFile = os.path.abspath(el[1])
if ("unittest/case.py" in currentFile) | ("org.python.pydev" in currentFile):
break
previous = currentFile
folder = previous
# We return the folder :
return os.path.dirname(folder)
else:
# We return the folder according to specified __file__ :
return os.path.dirname(os.path.realpath(_file_))
Simplest way is:
in script_1.py:
import subprocess
subprocess.call(['python3',<path_to_script_2.py>])
in script_2.py:
sys.argv[0]
P.S.: I've tried execfile, but since it reads script_2.py as a string, sys.argv[0] returned <string>.
The following returns the path where your current main script is located at. I tested this with Linux, Win10, IPython and Jupyter Lab. I needed a solution that works for local Jupyter notebooks as well.
import builtins
import os
import sys
def current_dir():
if "get_ipython" in globals() or "get_ipython" in dir(builtins):
# os.getcwd() is PROBABLY the dir that hosts the active notebook script.
# See also https://github.com/ipython/ipython/issues/10123
return os.getcwd()
else:
return os.path.abspath(os.path.dirname(sys.argv[0]))
Finding the home directory of the path in which your Python script resides
As an addendum to the other answers already here (and not answering the OP's question, since other answers already do that), if the path to your script is /home/gabriel/GS/dev/eRCaGuy_dotfiles/useful_scripts/cpu_logger.py, and you wish to obtain the home directory part of that path, which is /home/gabriel, you can do this:
import os
# Obtain the home dir of the user in whose home directory this script resides
script_path_list = os.path.normpath(__file__).split(os.sep)
home_dir = os.path.join("/", script_path_list[1], script_path_list[2])
To help make sense of this, here are the paths for __file__, script_path_list, and home_dir. Notice that script_path_list is a list of the path components, with the first element being an empty string since it originally contained the / root dir path separator for this Linux path:
__file__ = /home/gabriel/GS/dev/eRCaGuy_dotfiles/useful_scripts/cpu_logger.py
script_path_list = ['', 'home', 'gabriel', 'GS', 'dev', 'eRCaGuy_dotfiles', 'useful_scripts', 'cpu_logger.py']
home_dir = /home/gabriel
Source:
Python: obtain the path to the home directory of the user in whose directory the script being run is located [duplicate]

Categories

Resources