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.dic和input2.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,则在开始处不应该有前向或反向)