我正在构建一个简单的助手脚本,用于将代码库中的两个模板文件复制到当前目录。但是,我没有存储模板的目录的绝对路径。我有一个相对路径从脚本,但当我调用脚本,它把它作为一个相对于当前工作目录的路径。是否有一种方法来指定这个相对url是来自脚本的位置?


当前回答

以下是我的总结:

首先,定义名为relpath的工具函数,它将当前文件的相对路径转换为cwd的相对路径

import os
relpath = lambda p: os.path.normpath(os.path.join(os.path.dirname(__file__), p))

然后我们使用它来包装相对于当前文件的路径

path1 = relpath('../src/main.py')

你也可以调用sys.path.append()来导入相对于当前文件位置的文件

sys.path.append(relpath('..')) # so that you can import from upper dir

完整的示例代码:https://gist.github.com/luochen1990/9b1ffa30f5c4a721dab5991e040e3eb1

其他回答

根据其他建议和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()

我认为要在所有系统中使用“ntpath”而不是“os.path”。如今,它在Windows、Linux和Mac OSX上都能很好地工作。

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

一个简单的解决办法是

import os
os.chdir(os.path.dirname(__file__))

假设当前的存档文件名为“Helper”,上面的目录名为“Workshop”,模板文件在\Workshop\Templates中,那么Python中的相对路径为“..\Templates”。

最重要命令的摘要

>>> import os
>>> os.path.join('/home/user/tmp', 'subfolder')
'/home/user/tmp/subfolder'
>>> os.path.normpath('/home/user/tmp/../test/..')
'/home/user'
>>> os.path.relpath('/home/user/tmp', '/home/user')
'tmp'
>>> os.path.isabs('/home/user/tmp')
True
>>> os.path.isabs('/tmp')
True
>>> os.path.isabs('tmp')
False
>>> os.path.isabs('./../tmp')
False
>>> os.path.realpath('/home/user/tmp/../test/..') # follows symbolic links
'/home/user'

详细的描述可以在文档中找到。 这些是linux路径。Windows的工作原理与此类似。