Python中的相对path

我正在构build一个简单的帮助脚本,用于将我们的代码库中的几个模板文件复制到当前目录。 但是,我不具有存储模板的目录的绝对path。 我有一个从脚本的相对path,但是当我调用脚本它把它当作相对于当前工作目录的path。 有没有办法指定这个相对的URL是从脚本的位置,而不是?

在具有该脚本的文件中,您希望执行如下操作:

import os dir = os.path.dirname(__file__) filename = os.path.join(dir, '/relative/path/to/file/you/want') 

这会给你你正在寻找的文件的绝对path。 请注意,如果您使用setuptools,则应该使用其包资源API 。

更新 :我在这里回应评论,所以我可以粘贴一个代码示例。 🙂

我正确地认为__file__并不总是可用的(例如,当你直接运行文件,而不是导入它)?

当你提到直接运行文件时,我假定你的意思是__main__脚本。 如果是这样,我的系统似乎并不是这样(OS X 10.5.7上的python 2.5.1):

 #foo.py import os print os.getcwd() print __file__ #in the interactive interpreter >>> import foo /Users/jason foo.py #and finally, at the shell: ~ % python foo.py /Users/jason foo.py 

不过,我知道在C扩展中有一些与__file__有关的怪癖。 例如,我可以在我的Mac上执行此操作:

 >>> import collections #note that collections is a C extension in Python 2.5 >>> collections.__file__ '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib- dynload/collections.so' 

但是,这在我的Windows机器上引发了一个例外。

你需要os.path.realpath (下面的示例将父目录添加到你的path)

 import sys,os sys.path.append(os.path.realpath('..')) 

正如接受的答案中提到的那样

 import os dir = os.path.dirname(__file__) filename = os.path.join(dir, '/relative/path/to/file/you/want') 

我只是想补充一点

后面的string不能以反斜杠开始,实际上没有string应该包含反斜杠

应该是这样的

 import os dir = os.path.dirname(__file__) filename = os.path.join(dir, 'relative','path','to','file','you','want') 

在某些情况下,接受的答案可能会引起误解,请参阅此链接了解详情

请参阅sys.path在程序启动时初始化,此列表中的第一项path [0]是包含用于调用Python解释器的脚本的目录。

使用此path作为您应用相对path的根文件夹

 >>> import sys >>> import os.path >>> sys.path[0] 'C:\\Python25\\Lib\\idlelib' >>> os.path.relpath(sys.path[0], "path_to_libs") # if you have python 2.6 >>> os.path.join(sys.path[0], "path_to_libs") 'C:\\Python25\\Lib\\idlelib\\path_to_libs' 

考虑我的代码:

 import os def readFile(filename): filehandle = open(filename) print filehandle.read() filehandle.close() fileDir = os.path.dirname(os.path.realpath('__file__')) print fileDir #For accessing the file in the same folder filename = "same.txt" readFile(filename) #For accessing the file in a folder contained in the current folder filename = os.path.join(fileDir, 'Folder1.1/same.txt') readFile(filename) #For accessing the file in the parent folder of the current folder filename = os.path.join(fileDir, '../same.txt') readFile(filename) #For accessing the file inside a sibling folder. filename = os.path.join(fileDir, '../Folder2/same.txt') filename = os.path.abspath(os.path.realpath(filename)) print filename readFile(filename) 

而不是使用

 import os dirname = os.path.dirname(__file__) filename = os.path.join(dirname, '/relative/path/to/file/you/want') 

正如在接受的答案中那样,使用起来会更加健壮:

 import inspect import os dirname = os.path.dirname(os.path.abspath(inspect.stack()[0][1])) filename = os.path.join(dirname, '/relative/path/to/file/you/want') 

因为使用__file__将返回从其中加载模块的文件,如果它是从文件加载的,所以如果从其他地方调用带有该脚本的文件,返回的目录将不正确。

这些答案给出了更多的细节: https : //stackoverflow.com/a/31867043/5542253和https://stackoverflow.com/a/50502/5542253

这段代码将返回主脚本的绝对path。

 import os def whereAmI(): return os.path.dirname(os.path.realpath(__import__("__main__").__file__)) 

即使在一个模块中,这也可以工作。

嗨,首先你应该明白函数os.path.abspath(path)os.path.relpath(path)

简而言之, os.path.abspath(path)使绝对path相对 path 。 如果提供的path本身是绝对path,那么函数返回相同的path。

类似地os.path.relpath(path)使相对path绝对 path 。 如果提供的path本身是一个相对path,那么该函数返回相同的path。

下面的例子可以让你正确理解上面的概念

假设我有一个文件input_file_list.txt ,其中包含要由我的python脚本处理的input文件列表。

d:\浓度\ input1.dic

d:\浓度\ input2.dic

d:\ Copyioconc \ input_file_list.txt

如果您看到上面的文件夹结构,则在Copyofconc文件夹中存在input_file_list.txt ,并且由python脚本处理的文件存在于conc文件夹中

但是文件input_file_list.txt的内容如下所示:

.. \浓度\ input1.dic

.. \浓度\ input2.dic

而我的Python脚本存在于D:驱动器中。

input_file_list.txt文件中提供的相对path是相对于input_file_list.txt文件的path的。

所以当python脚本执行当前工作目录(使用os.getcwd()获取path)

由于我的相对path是相对于input_file_list.txt ,即“D:\ Copyofconc” ,我必须将当前工作目录更改为“D:\ Copyofconc”

所以我必须使用os.chdir('D:\ Copyofconc') ,所以当前的工作目录应该是“D:\ Copyofconc”

现在要获取文件input1.dicinput2.dic ,我将读取“.. \ conc \ input1.dic”行,然后使用命令

input1_path = os.path.abspath('.. \ conc \ input1.dic') (将相对path改为绝对path,当前工作目录为“D:\ Copyofconc”,文件为“。\ conc \ input1。 dic“应相对于”D:\ Copyofconc“访问)

所以input1_path应该是“D:\ conc \ input1.dic”

另一个适合我的方法是:

 this_dir = os.path.dirname(__file__) filename = os.path.realpath("{0}/relative/file.path".format(this_dir)) 

什么对我来说是使用sys.path.insert 。 然后我指定了我需要去的目录。 例如,我只需要上一个目录。

 import sys sys.path.insert(0, '../') 

我不确定这是否适用于某些旧版本,但我相信Python 3.3具有本机相对path支持。

例如,下面的代码应该在python脚本所在的文件夹中创build一个文本文件:

 open("text_file_name.txt", "w+t") 

(请注意,如果它是相对path,则在开始处不应该有前向或反向)