题
我有调用其他脚本文件的脚本,但我需要获取当前在进程中运行的文件的文件路径。
例如,假设我有三个文件。使用 执行文件:
script_1.py
来电script_2.py
.- 反过来,
script_2.py
来电script_3.py
.
如何获取文件名和路径 script_3.py
, 从里面的代码 script_3.py
, ,而不必将该信息作为参数传递 script_2.py
?
(执行 os.getcwd()
返回原始启动脚本的文件路径而不是当前文件的文件路径。)
解决方案
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
其他提示
2018年11月28日更新:
以下是 Python 2 和 3 的实验摘要。和
main.py - 运行 foo.py
foo.py - 运行 lib/bar.py
lib/bar.py - 打印文件路径表达式
| 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__ |
对于 Python 2,切换到包可能会更清楚,因此可以使用 from lib import bar
- 只需添加空 __init__.py
文件到两个文件夹。
对于Python 3, execfile
不存在 - 最接近的替代方案是 exec(open(<filename>).read())
, ,尽管这会影响堆栈帧。最简单的就是使用 import foo
和 import lib.bar
- 不 __init__.py
需要的文件。
也可以看看 import 和 execfile 之间的区别
原答案:
这是基于此线程中答案的实验 - 在 Windows 上使用 Python 2.7.10。
基于堆栈的方法似乎是唯一能够提供可靠结果的方法。最后两个语法最短, , IE。-
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
这是要添加到的 系统 作为函数!感谢@Usagi 和@pablog
基于以下三个文件,并从其文件夹中运行 main.py python main.py
(还尝试使用绝对路径的 execfiles 并从单独的文件夹调用)。
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
我认为这更干净:
import inspect
print inspect.stack()[0][1]
并获得与以下相同的信息:
print inspect.getfile(inspect.currentframe())
其中 [0] 是堆栈中的当前帧(堆栈顶部),[1] 是文件名,增加以在堆栈中向后移动,即
print inspect.stack()[1][1]
将是调用当前帧的脚本的文件名。另外,使用 [-1] 将使您到达堆栈的底部,即原始调用脚本。
import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only
如果您的脚本仅包含一个文件,则标记为最佳的建议都是正确的。
如果您想找出可执行文件的名称(即从可能作为模块导入的文件传递给当前程序的 python 解释器的根文件),您需要执行此操作(假设这是在名为 foo.py):
import inspect
print inspect.stack()[-1][1]
因为最后一件事([-1]
)在堆栈上是第一个进入它的东西(堆栈是 LIFO/FILO 数据结构)。
然后在文件中 酒吧.py 如果你 import foo
它会打印 酒吧.py, , 而不是 foo.py, ,这将是所有这些的值:
__file__
inspect.getfile(inspect.currentframe())
inspect.stack()[0][1]
import os
print os.path.basename(__file__)
这只会给我们文件名。IE。如果文件的绝对路径是 c:\abcd\abc.py 那么第二行将打印 abc.py
目前尚不完全清楚“当前正在进程中运行的文件的文件路径”的含义。sys.argv[0]
通常包含Python解释器调用的脚本的位置。检查 系统文档 更多细节。
正如 @Tim 和 @Pat Notz 所指出的, __file__ 属性提供对
如果文件是从文件加载的,则加载了该模块的文件
我有一个必须在Windows环境下运行的脚本。这段代码是我完成的:
import os,sys
PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])
这是一个相当狡猾的决定。但它不需要外部库,这对我来说是最重要的。
import os
os.path.dirname(os.path.abspath(__file__))
不需要检查或任何其他库。
当我必须导入一个脚本(从与执行的脚本不同的目录)时,这对我有用,该脚本使用与导入的脚本位于同一文件夹中的配置文件。
这 __file__
属性适用于包含主执行代码的文件以及导入的模块。
看 https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__
import sys
print sys.path[0]
这将打印当前正在执行的脚本的路径
我认为这只是 __file__
听起来您可能还想查看 检查模块.
您可以使用 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.realpath(__file__))
import sys
print sys.argv[0]
这应该有效:
import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))
获取执行脚本的目录
print os.path.dirname( inspect.getfile(inspect.currentframe()))
要保持跨平台(macOS/Windows/Linux)的迁移一致性,请尝试:
path = r'%s' % os.getcwd().replace('\\','/')
print(__file__)
print(__import__("pathlib").Path(__file__).parent)
我使用了 __file__ 的方法
os.path.abspath(__file__)
但是有一个小技巧,它在第一次运行代码时返回.py文件,接下来运行给出 *.pyc文件的名称
所以我留下来:
inspect.getfile(inspect.currentframe())
或者
sys._getframe().f_code.co_filename
我写了一个考虑到eclipse的函数 调试器 和 单元测试。它返回您启动的第一个脚本的文件夹。您可以选择指定 __文件__ var,但最主要的是你不必在所有的程序中共享这个变量 调用层次结构.
也许你可以处理其他堆栈我没有看到的特殊情况,但对我来说没关系。
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_))
最简单的方法是:
在 script_1.py:
import subprocess
subprocess.call(['python3',<path_to_script_2.py>])
在 script_2.py:
sys.argv[0]
附:我试过了 execfile
, ,但由于它将 script_2.py 作为字符串读取, sys.argv[0]
回 <string>
.
我一直只使用当前工作目录(CWD)的操作系统功能。这是标准库的一部分,并且非常容易实现。这是一个例子:
import os
base_directory = os.getcwd()
大多数答案都是用 Python 2.x 或更早版本编写的。在 Python 3.x 中,打印函数的语法已更改为需要括号,即打印()。
因此,Python 2.x 中 user13993 的早期高分答案:
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
Python 3.x 中变为:
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
如果你只想要文件名而不 ./
或者 .py
你可以试试这个
filename = testscript.py
file_name = __file__[2:-3]
file_name
将打印testscript,您可以通过更改内部的索引来生成想要的任何东西[
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)