如何创建以点为起点的相对路径 pathlib?

8

我需要创建一个相对路径,以当前目录为"."点开始

例如,在Windows中使用“.\envs\.some.env”,在其他地方使用“./envs/.some.env”

我想使用pathlib来实现这一点。已经找到了一个解决方案,但它有一个笨拙的替换语句。是否有更好的方法可以使用pathlib来实现这个目标?

使用django-environ时,目标是支持多个env文件。工作文件夹包含一个envs文件夹,该文件夹中包含多个env文件。

import environ
from pathlib import Path
import os

domain_env = Path.cwd()

dotdot = Path("../")
some_env = dotdot / "envs" / ".some.env"

envsome = environ.Env()
envsome.read_env(envsome.str(str(domain_env), str(some_env).replace("..", ".")))  

print(str(some_env))
print(str(some_env).replace("..", "."))

dot = Path("./")    # Path(".") gives the same result
some_env = dot / "envs" / ".some.env"

print(str(some_env))

在Windows上会给出以下信息:
..\envs\.some.env
.\envs\.some.env
envs\.some.env

为什么 envs\.some.env 不够用?对于像 Path('envs\\.some.env').open()Path('.\\envs\\.some.env').open() 这样的常见用法,它们应该是相同的。 - Hans Musgrave
".\" 是当前目录,可以省略。 - metatoaster
感谢快速的回复。使用django-environ模块,我唯一能让它工作的方式是在当前目录中加入点。然后我想迁移到pathlib解决方案。 - bearcat
最后只需简单地使用os.path.join('。',str(some_env))即可。 - metatoaster
1
是的,那样做可以,而且在某些情况下,os库比pathlib库具有更多的功能。这可能是其中之一。我在想是否有一种pathlib的方法来解决这个问题。 - bearcat
1
我刚刚也遇到了这个确切的问题,因为我正在创建一个路径,将其传递给nodejs的require()语句,在那里./something.jssomething.js被解释为不同的内容。 - user3064538
2个回答

4
我找到的最好的答案是(正如问题评论中metatoaster所建议的):
os.path.join(".", some_env)

其中,some_env 可以是字符串或 bytes 或 (自 Python 3.6 起) 任何 类似路径的对象(这意味着您不再需要将 Path 对象转换为字符串)。
由于有些人想知道这可能有什么用处:
  • 当前目录中的 shell 脚本 foo.sh 不能使用 foo.sh 调用(除非 .$PATH 中),而必须使用 ./foo.sh 调用。
  • Boris 所解释的那样,在 Node.js 的 require() 语句中,foo./foo 之间有区别。
  • 我自己需要这个来创建一个文件名参数以传递给 ExifTool,该参数保证不会被解析为命令行选项,即使文件名例如为 -quiet。ExifTool 不遵循 Unix 惯例,即没有一个 -- 参数表示以下所有参数都不是选项,其作者的官方建议是“如果文件名以破折号开头,请将目录名称放在文件名之前”。

2

这是一个跨平台的想法:

import ntpath
import os
import posixpath
from pathlib import Path, PurePosixPath, PureWindowsPath


def dot_path(pth):
    """Return path str that may start with '.' if relative."""
    if pth.is_absolute():
        return os.fsdecode(pth)
    if isinstance(pth, PureWindowsPath):
        return ntpath.join(".", pth)
    elif isinstance(pth, PurePosixPath):
        return posixpath.join(".", pth)
    else:
        return os.path.join(".", pth)


print(dot_path(PurePosixPath("file.txt")))    # ./file.txt
print(dot_path(PureWindowsPath("file.txt")))  # .\file.txt
print(dot_path(Path("file.txt")))             # one of the above, depending on host OS
print(dot_path(Path("file.txt").resolve()))   # (e.g.) /path/to/file.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接