如何获得当前正在执行的文件的路径和名称?

时间:2021-10-28 16:29:58

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:

例如,假设我有三个文件。使用execfile:

  • script_1.py calls script_2.py.
  • script_1。py script_2.py的电话。
  • In turn, script_2.py calls script_3.py.
  • 反过来,script_2。py 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?

如何获得script_3的文件名和路径。py,来自script_3中的代码。py,不需要从script_2。py作为参数传递信息吗?

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

(执行os.getcwd()返回原始启动脚本的文件路径,而不是当前文件的文件路径)。

23 个解决方案

#1


212  

p1.py:

p1.py:

execfile("p2.py")

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

#2


451  

__file__

as others have said. You may also want to use os.path.realpath to eliminate symlinks:

正如别人所说。您可能还想使用os.path。realpath消除符号链接:

import os

os.path.realpath(__file__)

#3


62  

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

下面是一个基于该线程的答案的实验——在Windows上使用Python 2.7.10。

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

下面是添加到sys中的函数!信用@Usagi和@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).

基于以下三个文件,并运行script1。使用python script1从其文件夹中获取py。py(也尝试使用绝对路径和从单独的文件夹调用execfiles)。

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

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

#4


59  

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.

其中[0]是堆栈中的当前帧(堆栈的顶部),[1]是文件名,在堆栈中增加为向后。

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.

将是调用当前帧的脚本的文件名。另外,使用[-1]将使您到达堆栈的底部,即原始的调用脚本。

#5


33  

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

#6


32  

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

如果您的脚本只包含一个文件,那么标记为best的建议都是正确的。

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):

如果您想从作为模块导入的文件中查找可执行文件的名称(即传递给当前程序的python解释器的根文件),您需要这样做(假设这是在一个名为foo.py的文件中):

import inspect

进口检查

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

打印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).

因为堆栈上的最后一个东西([-1])是进入堆栈的第一个东西(堆栈是LIFO/FILO数据结构)。

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:

然后在文件栏。如果你导入foo,它会打印bar。py,而不是foo。py,也就是所有这些的值

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

#7


13  

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

这将只给我们文件名。例如,如果文件abspath是c:\abcd\abc。然后第二行打印abc

#8


11  

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.

不完全清楚您所说的“进程中当前运行的文件的文件路径”是什么意思。sys。argv[0]通常包含Python解释器调用的脚本的位置。详细信息请参阅sys文档。

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

正如@Tim和@Pat Notz所指出的,__file__属性提供了访问权。

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

从文件中加载模块的文件

#9


8  

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

我有一个必须在windows环境下运行的脚本。这段代码被剪掉了,我已经完成了:

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.

这是一项相当不明智的决定。但它不需要外部库,这对我来说是最重要的。

#10


7  

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

__file__属性既适用于包含主执行代码的文件,也适用于导入的模块。

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

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

#11


5  

import sys

print sys.path[0]

this would print the path of the currently executing script

这将打印当前执行脚本的路径

#12


5  

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.

当我必须导入一个脚本(从不同的目录然后是执行的脚本)时,这对我来说是可行的,这个脚本使用与导入脚本位于同一文件夹中的配置文件。

#13


5  

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

我认为它只是__file__听起来您可能也想签出inspect模块。

#14


4  

You can use inspect.stack()

您可以使用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'

#15


3  

import sys
print sys.argv[0]

#16


2  

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]))

#17


1  

To keep the migration consistency across platforms (macOS/Windows/Linux), try:

为了保持跨平台(macOS/Windows/Linux)的迁移一致性,请尝试:

path = r'%s' % os.getcwd().replace('\\','/')

path = r'%s' % os.getcwd().replace('\ ','/')

#18


0  

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

我使用了__file__ .path.abspath(__file__)的方法,但是有一个小技巧,它在第一次运行代码时返回.py文件,下次运行时给出*的名称。pyc文件,所以我留下了:检查。getfile(检查。currentframe())或sys._getframe().f_code.co_filename。

#19


0  

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.

我编写了一个函数,它考虑了eclipse调试器和unittest。它返回您启动的第一个脚本的文件夹。您可以选择指定__file__ var,但最重要的是,您不必在所有调用层次结构*享此变量。

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://*.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_))

#20


0  

To get directory of executing script

获取执行脚本的目录

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

#21


0  

Simplest way is:

简单的方法是:

in script_1.py:

在script_1.py:

import subprocess
subprocess.call(['python3',<path_to_script_2.py>])

in script_2.py:

在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>.

注::我试过execfile,但是因为它读script_2。py作为一个字符串,sys。argv[0] <字符串> 返回。

#22


-1  

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)

#23


-2  

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

如果你只想要没有./或.py的文件名,你可以试试这个

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

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

file_name将打印testscript您可以通过在[]中修改索引来生成所需的任何内容

#1


212  

p1.py:

p1.py:

execfile("p2.py")

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

#2


451  

__file__

as others have said. You may also want to use os.path.realpath to eliminate symlinks:

正如别人所说。您可能还想使用os.path。realpath消除符号链接:

import os

os.path.realpath(__file__)

#3


62  

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

下面是一个基于该线程的答案的实验——在Windows上使用Python 2.7.10。

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

下面是添加到sys中的函数!信用@Usagi和@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).

基于以下三个文件,并运行script1。使用python script1从其文件夹中获取py。py(也尝试使用绝对路径和从单独的文件夹调用execfiles)。

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

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

#4


59  

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.

其中[0]是堆栈中的当前帧(堆栈的顶部),[1]是文件名,在堆栈中增加为向后。

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.

将是调用当前帧的脚本的文件名。另外,使用[-1]将使您到达堆栈的底部,即原始的调用脚本。

#5


33  

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

#6


32  

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

如果您的脚本只包含一个文件,那么标记为best的建议都是正确的。

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):

如果您想从作为模块导入的文件中查找可执行文件的名称(即传递给当前程序的python解释器的根文件),您需要这样做(假设这是在一个名为foo.py的文件中):

import inspect

进口检查

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

打印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).

因为堆栈上的最后一个东西([-1])是进入堆栈的第一个东西(堆栈是LIFO/FILO数据结构)。

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:

然后在文件栏。如果你导入foo,它会打印bar。py,而不是foo。py,也就是所有这些的值

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

#7


13  

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

这将只给我们文件名。例如,如果文件abspath是c:\abcd\abc。然后第二行打印abc

#8


11  

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.

不完全清楚您所说的“进程中当前运行的文件的文件路径”是什么意思。sys。argv[0]通常包含Python解释器调用的脚本的位置。详细信息请参阅sys文档。

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

正如@Tim和@Pat Notz所指出的,__file__属性提供了访问权。

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

从文件中加载模块的文件

#9


8  

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

我有一个必须在windows环境下运行的脚本。这段代码被剪掉了,我已经完成了:

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.

这是一项相当不明智的决定。但它不需要外部库,这对我来说是最重要的。

#10


7  

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

__file__属性既适用于包含主执行代码的文件,也适用于导入的模块。

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

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

#11


5  

import sys

print sys.path[0]

this would print the path of the currently executing script

这将打印当前执行脚本的路径

#12


5  

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.

当我必须导入一个脚本(从不同的目录然后是执行的脚本)时,这对我来说是可行的,这个脚本使用与导入脚本位于同一文件夹中的配置文件。

#13


5  

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

我认为它只是__file__听起来您可能也想签出inspect模块。

#14


4  

You can use inspect.stack()

您可以使用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'

#15


3  

import sys
print sys.argv[0]

#16


2  

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]))

#17


1  

To keep the migration consistency across platforms (macOS/Windows/Linux), try:

为了保持跨平台(macOS/Windows/Linux)的迁移一致性,请尝试:

path = r'%s' % os.getcwd().replace('\\','/')

path = r'%s' % os.getcwd().replace('\ ','/')

#18


0  

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

我使用了__file__ .path.abspath(__file__)的方法,但是有一个小技巧,它在第一次运行代码时返回.py文件,下次运行时给出*的名称。pyc文件,所以我留下了:检查。getfile(检查。currentframe())或sys._getframe().f_code.co_filename。

#19


0  

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.

我编写了一个函数,它考虑了eclipse调试器和unittest。它返回您启动的第一个脚本的文件夹。您可以选择指定__file__ var,但最重要的是,您不必在所有调用层次结构*享此变量。

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://*.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_))

#20


0  

To get directory of executing script

获取执行脚本的目录

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

#21


0  

Simplest way is:

简单的方法是:

in script_1.py:

在script_1.py:

import subprocess
subprocess.call(['python3',<path_to_script_2.py>])

in script_2.py:

在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>.

注::我试过execfile,但是因为它读script_2。py作为一个字符串,sys。argv[0] <字符串> 返回。

#22


-1  

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)

#23


-2  

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

如果你只想要没有./或.py的文件名,你可以试试这个

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

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

file_name将打印testscript您可以通过在[]中修改索引来生成所需的任何内容