我正在构建一个简单的助手脚本,用于将代码库中的两个模板文件复制到当前目录。但是,我没有存储模板的目录的绝对路径。我有一个相对路径从脚本,但当我调用脚本,它把它作为一个相对于当前工作目录的路径。是否有一种方法来指定这个相对url是来自脚本的位置?
当前回答
这段代码将返回主脚本的绝对路径。
import os
def whereAmI():
return os.path.dirname(os.path.realpath(__import__("__main__").__file__))
这甚至可以在一个模块中工作。
其他回答
看到sys.path 在程序启动时初始化后,该列表的第一项路径[0]是包含用于调用Python解释器的脚本的目录。
使用此路径作为根文件夹,从中应用相对路径
>>> 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)
假设当前的存档文件名为“Helper”,上面的目录名为“Workshop”,模板文件在\Workshop\Templates中,那么Python中的相对路径为“..\Templates”。
Hi首先你需要理解os。path。abspath(path)和os。path。relpath(path)
简而言之,os.path.abspath(path)将相对路径转换为绝对路径。如果提供的路径本身是一个绝对路径,那么函数返回相同的路径。
类似地,os.path.relpath(path)将绝对路径转换为相对路径。如果提供的路径本身是相对路径,则函数返回相同的路径。
下面的例子可以让你正确理解上面的概念:
假设我有一个文件input_file_list.txt,其中包含要由我的python脚本处理的输入文件列表。
D: \ \ input1.dic浓缩
D: \ \ input2.dic浓缩
D: \ Copyioconc input_file_list。txt
如果你看到上面的文件夹结构,input_file_list.txt在Copyofconc文件夹中,python脚本要处理的文件在conc文件夹中
但是input_file_list.txt文件的内容如下所示:
. . \ \ input1.dic浓缩
. . \ \ input2.dic浓缩
我的python脚本在D: drive中。
input_file_list.txt文件中提供的相对路径是相对于input_file_list.txt文件的路径。
因此,当python脚本执行当前工作目录时(使用os.getcwd()获取路径)
由于我的相对路径是相对于input_file_list.txt,即“D:\Copyofconc”,我必须将当前工作目录更改为“D:\Copyofconc”。
所以我必须使用os.chdir('D:\Copyofconc'),所以当前的工作目录应该是“D:\Copyofconc”。
现在获取文件input1。Dic和input2。Dic,我将读取“..\conc\input1”这行。然后使用命令
Input1_path = os.path.abspath('..\conc\input1.dic')(将相对路径更改为绝对路径。这里作为当前的工作目录是“D:\Copyofconc”,文件“.\conc\input1.”相对于"D:\Copyofconc")
所以input1_path应该是“D:\conc\input1.dic”
现在是2018年,Python很久以前就已经进化到__future__了。因此,如何使用Python 3.4附带的惊人的pathlib来完成任务,而不是在os, os中苦苦挣扎。路径,glob, shutil等。
这里有3条路径(可能重复):
Mod_path:简单帮助脚本的路径 Src_path:包含两个等待复制的模板文件。 Cwd:当前目录,这些模板文件的目的地。
问题是:我们没有src_path的完整路径,只知道它到mod_path的相对路径。
现在让我们用惊人的pathlib来解决这个问题:
# Hope you don't be imprisoned by legacy Python code :)
from pathlib import Path
# `cwd`: current directory is straightforward
cwd = Path.cwd()
# `mod_path`: According to the accepted answer and combine with future power
# if we are in the `helper_script.py`
mod_path = Path(__file__).parent
# OR if we are `import helper_script`
mod_path = Path(helper_script.__file__).parent
# `src_path`: with the future power, it's just so straightforward
relative_path_1 = 'same/parent/with/helper/script/'
relative_path_2 = '../../or/any/level/up/'
src_path_1 = (mod_path / relative_path_1).resolve()
src_path_2 = (mod_path / relative_path_2).resolve()
在未来,就这么简单。
此外,我们可以使用pathlib选择、检查和复制/移动这些模板文件:
if src_path != cwd:
# When we have different types of files in the `src_path`
for template_path in src_path.glob('*.ini'):
fname = template_path.name
target = cwd / fname
if not target.exists():
# This is the COPY action
with target.open(mode='wb') as fd:
fd.write(template_path.read_bytes())
# If we want MOVE action, we could use:
# template_path.replace(target)