我正在构建一个简单的助手脚本,用于将代码库中的两个模板文件复制到当前目录。但是,我没有存储模板的目录的绝对路径。我有一个相对路径从脚本,但当我调用脚本,它把它作为一个相对于当前工作目录的路径。是否有一种方法来指定这个相对url是来自脚本的位置?
当前回答
这是向系统路径集添加相对路径的简单方法。例如,对于目标目录比工作目录高一级(例如'/../')的常见情况:
import os
import sys
workingDir = os.getcwd()
targetDir = os.path.join(os.path.relpath(workingDir + '/../'),'target_directory')
sys.path.insert(0,targetDir)
对该解决方案进行了测试:
Python 3.9.6 |由conda-forge |打包(默认,2021年7月11日, 03:37:25) [MSC .1916 64位(AMD64)]
其他回答
考虑一下我的代码:
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)
根据其他建议和pathlib文档,一个简单(但不理想)的解决方案如下(假设我们需要引用的文件是Test/data/users.csv):
# Current file location: Tests/src/long/module/subdir/some_script.py
from pathlib import Path
# back to Tests/
PROJECT_ROOT = Path(__file__).parents[4]
# then down to Test/data/users.csv
CSV_USERS_PATH = PROJECT_ROOT / 'data' / 'users.csv'
with CSV_USERS_PATH.open() as users:
print(users.read())
这是可行的,但看起来有点奇怪,因为如果您移动some_script.py,到项目根目录的路径可能会改变(因此我们需要更改父目录[4]部分)。
我想我找到了一个更好的解决方案,基于同样的想法。 我们将使用path .py文件来存储项目的根目录,与根目录相比,这个文件将保持在相同的位置。
Tests
├── data
│ └── users.csv
└── src
├── long
│ └── module
│ └── subdir
│ └── some_script.py
├── main.py
└── paths.py
path .py的唯一职责是提供PROJECT_ROOT:
from pathlib import Path
PROJECT_ROOT = Path(__file__).parents[1]
所有脚本现在都可以使用路径。PROJECT_ROOT表示从项目根开始的绝对路径。例如,在src/long/module/subdir/some_script.py中,我们可以有:
from paths import PROJECT_ROOT
CSV_USERS_PATH = PROJECT_ROOT / 'data' / 'users.csv'
def hello():
with CSV_USERS_PATH.open() as f:
print(f.read())
一切都如你所料:
~/Tests/src/$ python main.py
/Users/cglacet/Tests/data/users.csv
hello, user
~/Tests/$ python src/main.py
/Users/cglacet/Tests/data/users.csv
hello, user
main.py脚本就是:
from long.module.subdir import some_script
some_script.hello()
现在是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)
另一个适合我的选择是:
this_dir = os.path.dirname(__file__)
filename = os.path.realpath("{0}/relative/file.path".format(this_dir))
这是向系统路径集添加相对路径的简单方法。例如,对于目标目录比工作目录高一级(例如'/../')的常见情况:
import os
import sys
workingDir = os.getcwd()
targetDir = os.path.join(os.path.relpath(workingDir + '/../'),'target_directory')
sys.path.insert(0,targetDir)
对该解决方案进行了测试:
Python 3.9.6 |由conda-forge |打包(默认,2021年7月11日, 03:37:25) [MSC .1916 64位(AMD64)]
推荐文章
- 如何用OpenCV2.0和Python2.6调整图像大小
- 在每个列表元素上调用int()函数?
- 当使用代码存储库时,如何引用资源的相对路径
- 如何在Flask-SQLAlchemy中按id删除记录
- 在OSX中永久设置PATH环境变量
- 在Python中插入列表的第一个位置
- Python Pandas只合并某些列
- 如何在一行中连接两个集而不使用“|”
- 从字符串中移除前缀
- 代码结束时发出警报
- 如何在Python中按字母顺序排序字符串中的字母
- 在matplotlib中将y轴标签添加到次要y轴
- 如何消除数独方块的凹凸缺陷?
- 为什么出现这个UnboundLocalError(闭包)?
- 使用Python请求的异步请求