I have 4 python script files.
script_1.py
script_2.py
script_3.py
script_4.py
script_1.py, script_2.py and script_3.py calls script_4.py
Execute files always change.
Like, python script_1.py / python script_2.py / python script_3.py
I want to get script_1.py, script_2.py, and script_3.py file name in script_4.py python script.
How can I get current executing file name without having to pass that information as arguments?
I tried __name__ and inspect.getfile(inspect.currentframe()) but no luck.
Both of codes are returns script_4.py.
When called, sys.argv holds the command line arguments. The first element is the name of the script that was called (including path). To get the name of the script that was originally called you can do, in any of your files:
import os
import sys
called_script_with_path = sys.argv[0]
called_script_without_path = os.path.basename(sys.argv[0])
You can use the module level attribute __file__ to get the path to the current module.
>>> import os
>>> os.path.basename(__file__)
test.py
If you want to determine this for another file, you can import the script and still query the value:
>>> import os
>>> import script1
>>> os.path.basename(script1.__file__)
script1.py
I have a script myScript.py with a function myFunc(a, b). How can I use subprocess module to run this function on a given conda environment with a given arguments? The solution which I would like to obtain is:
import subprocess
result = subprocess.run(["path\to\python", nameOfFunction, arguments a and b])
where result is a result of a function myFunc(a,b).
you can simply do this
import subprocess
result = subprocess.run(["path\to\python", "-c","import pyfile;myFunc(5, 10)"])
but if your file is in another directory
you can use two ways
this going to append directory path to python sys paths
import sys;sys.path.append("path\to\pyfile/directory")
then import it
or
import os;os.chdir("path\to\pyfile/directory")
learn more about os.chdir and sys.path
if you don't know why did i put the -c in subprocess.run, here something that will be helpful python cmdline
Can someone give me a tip on how I can use os to run a different .py file from my python script? This code below works, but only because I specify the complete file path.
How can I modify the code to incorporate running plots.py from the same directory as my main script app.py? Im using Windows at the moment but hoping it can work on any operating system. Thanks
import os
os.system('py C:/Users/benb/Desktop/flaskEconServer/plots.py')
You can execute an arbitrary Python script as a separate process using the subprocess.run() function something like this:
import os
import subprocess
import sys
#py_filepath = 'C:/Users/benb/Desktop/flaskEconServer/plots.py'
py_filepath = 'plots_test.py'
args = '"%s" "%s" "%s"' % (sys.executable, # command
py_filepath, # argv[0]
os.path.basename(py_filepath)) # argv[1]
proc = subprocess.run(args)
print('returncode:', proc.returncode)
If you would like to communicate with the process while it's running, that can also be done, plus there are other subprocess functions, including the lower-level but very general subprocess.Popen class that support doing those kind of things.
Python has built-in support for executing other scripts, without the need for the os module.
Try:
from . import plots
If you want to execute it in an independent python process, look into the multiprocessing or subprocess modules.
You can get the directory of the app.py file by using the following call in app.py
dir_path = os.path.dirname(os.path.realpath(__file__))
then join the file name you want
file_path = os.path.join(dir_path,'plot.py')
Finally your system call
os.system(f'py {file_path}') # if you're on 3.6 and above.
os.system('py %s' % file_path) # 3.5 and below
As others have said sub-processes and multi-threading may be better, but for your specific question this is what you want.
Is there a universal approach in Python, to find out the path to the file that is currently executing?
Failing approaches
path = os.path.abspath(os.path.dirname(sys.argv[0]))
This does not work if you are running from another Python script in another directory, for example by using execfile in 2.x.
path = os.path.abspath(os.path.dirname(__file__))
I found that this doesn't work in the following cases:
py2exe doesn't have a __file__ attribute, although there is a workaround
When the code is run from IDLE using execute(), in which case there is no __file__ attribute
On Mac OS X v10.6 (Snow Leopard), I get NameError: global name '__file__' is not defined
Test case
Directory tree
C:.
| a.py
\---subdir
b.py
Content of a.py
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
Content of subdir/b.py
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
Output of python a.py (on Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
Related (but these answers are incomplete)
Find path to currently running file
Path to current file depends on how I execute the program
How can I know the path of the running script in Python?
Change directory to the directory of a Python script
First, you need to import from inspect and os
from inspect import getsourcefile
from os.path import abspath
Next, wherever you want to find the source file from you just use
abspath(getsourcefile(lambda:0))
You can't directly determine the location of the main script being executed. After all, sometimes the script didn't come from a file at all. For example, it could come from the interactive interpreter or dynamically generated code stored only in memory.
However, you can reliably determine the location of a module, since modules are always loaded from a file. If you create a module with the following code and put it in the same directory as your main script, then the main script can import the module and use that to locate itself.
some_path/module_locator.py:
def we_are_frozen():
# All of the modules are built-in to the interpreter, e.g., by py2exe
return hasattr(sys, "frozen")
def module_path():
encoding = sys.getfilesystemencoding()
if we_are_frozen():
return os.path.dirname(unicode(sys.executable, encoding))
return os.path.dirname(unicode(__file__, encoding))
some_path/main.py:
import module_locator
my_path = module_locator.module_path()
If you have several main scripts in different directories, you may need more than one copy of module_locator.
Of course, if your main script is loaded by some other tool that doesn't let you import modules that are co-located with your script, then you're out of luck. In cases like that, the information you're after simply doesn't exist anywhere in your program. Your best bet would be to file a bug with the authors of the tool.
This solution is robust even in executables:
import inspect, os.path
filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
I was running into a similar problem, and I think this might solve the problem:
def module_path(local_function):
''' returns the module path without the use of __file__. Requires a function defined
locally in the module.
from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
return os.path.abspath(inspect.getsourcefile(local_function))
It works for regular scripts and in IDLE. All I can say is try it out for others!
My typical usage:
from toolbox import module_path
def main():
pass # Do stuff
global __modpath__
__modpath__ = module_path(main)
Now I use _modpath_ instead of _file_.
You have simply called:
path = os.path.abspath(os.path.dirname(sys.argv[0]))
instead of:
path = os.path.dirname(os.path.abspath(sys.argv[0]))
abspath() gives you the absolute path of sys.argv[0] (the filename your code is in) and dirname() returns the directory path without the filename.
The short answer is that there is no guaranteed way to get the information you want, however there are heuristics that work almost always in practice. You might look at How do I find the location of the executable in C?. It discusses the problem from a C point of view, but the proposed solutions are easily transcribed into Python.
See my answer to the question Importing modules from parent folder for related information, including why my answer doesn't use the unreliable __file__ variable. This simple solution should be cross-compatible with different operating systems as the modules os and inspect come as part of Python.
First, you need to import parts of the inspect and os modules.
from inspect import getsourcefile
from os.path import abspath
Next, use the following line anywhere else it's needed in your Python code:
abspath(getsourcefile(lambda:0))
How it works:
From the built-in module os (description below), the abspath tool is imported.
OS routines for Mac, NT, or Posix depending on what system we're on.
Then getsourcefile (description below) is imported from the built-in module inspect.
Get useful information from live Python objects.
abspath(path) returns the absolute/full version of a file path
getsourcefile(lambda:0) somehow gets the internal source file of the lambda function object, so returns '<pyshell#nn>' in the Python shell or returns the file path of the Python code currently being executed.
Using abspath on the result of getsourcefile(lambda:0) should make sure that the file path generated is the full file path of the Python file.
This explained solution was originally based on code from the answer at How do I get the path of the current executed file in Python?.
This should do the trick in a cross-platform way (so long as you're not using the interpreter or something):
import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))
sys.path[0] is the directory that your calling script is in (the first place it looks for modules to be used by that script). We can take the name of the file itself off the end of sys.argv[0] (which is what I did with os.path.basename). os.path.join just sticks them together in a cross-platform way. os.path.realpath just makes sure if we get any symbolic links with different names than the script itself that we still get the real name of the script.
I don't have a Mac; so, I haven't tested this on one. Please let me know if it works, as it seems it should. I tested this in Linux (Xubuntu) with Python 3.4. Note that many solutions for this problem don't work on Macs (since I've heard that __file__ is not present on Macs).
Note that if your script is a symbolic link, it will give you the path of the file it links to (and not the path of the symbolic link).
You can use Path from the pathlib module:
from pathlib import Path
# ...
Path(__file__)
You can use call to parent to go further in the path:
Path(__file__).parent
Simply add the following:
from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)
Or:
from sys import *
print(sys.argv[0])
If the code is coming from a file, you can get its full name
sys._getframe().f_code.co_filename
You can also retrieve the function name as f_code.co_name
The main idea is, somebody will run your python code, but you need to get the folder nearest the python file.
My solution is:
import os
print(os.path.dirname(os.path.abspath(__file__)))
With
os.path.dirname(os.path.abspath(__file__))
You can use it with to save photos, output files, ...etc
import os
current_file_path=os.path.dirname(os.path.realpath('__file__'))
/home/bar/foo/test.py:
I am trying test.py to print /home/bar/foo irrespective of from where I run the script from:
import os
def foo():
print os.getcwd()
test run:
[/home/bar $] python /home/bar/foo/test.py # echoes /home/bar
[/tmp $] python /home/bar/foo/test.py # echoes /tmp
os.getcwd() not the function for the task. How can I get this done otherwise?
Try this:
import os.path
p = os.path.abspath(__file__)
The __file__ variable will contain the location of the individual Python file.
If the script is somewhere in your path, then yes, you can strip it from sys.argv
#!/usr/bin/env python
import sys
import os
print sys.argv
print os.path.split(sys.argv[0])
dan#somebox:~$ test.py
['/home/dan/bin/test.py']
('/home/dan/bin', 'test.py')
Place this in a file and then run it.
import inspect, os.path
def codepath(function):
path = inspect.getfile(function)
if os.path.isabs(path): return path
else: return os.path.abspath(os.path.join(os.getcwd(), path))
print codepath(codepath)
My tests show that this prints the absolute path of the Python script whether it is run with an absolute path or not. I also tested it successfully when importing it from another folder. The only requirement is that a function or equivalent callable be present in the file.
As others have noted, you can use __file__ attribute of module objects.
Although, I'd like to note that in general, not-Python, case, you could've use sys.argv[0] for the same purpose. It's a common convention among different shells to pass full absolute pathname of the program through argv[0].
import sys
print sys.path[0]
This will give you the full path to your script every time, whereas __file__ will give you the path that was used to execute the script. 'sys.path' always has the path to the script as the first element, which allows one to always be able to import other .py files in the same directory.