【问题标题】:How to insert a directory in the middle of a file path in Python?如何在 Python 中的文件路径中间插入目录?
【发布时间】:2019-08-19 19:06:06
【问题描述】:

我想在给定文件路径的中间插入一个目录名,如下所示:

directory_name = 'new_dir'
file_path0 = 'dir1/dir2/dir3/dir4/file.txt'
file_path1 = some_func(file_path0, directory_name, position=2)
print(file_path1)
>>> 'dir1/dir2/new_dir/dir3/dir4/file.txt'

我查看了 os.path 和 pathlib 包,但看起来它们没有允许在文件路径中间插入的功能。我试过了:

import sys,os
from os.path import join

path_ = file_path0.split(os.sep)
path_.insert(2, 'new_dir')
print(join(path_))

但这会导致错误

“预期的 str、字节或 os.PathLike 对象,而不是列表”

有谁知道允许在文件路径中间插入的标准 python 函数?或者-我如何将path_ 转换为os.path 可以处理的东西。我是 pathlib 的新手,所以也许我错过了一些东西


编辑:根据问题的答案,我可以提出以下解决方案:

1.) 正如 Zach Favakeh 所建议和在this answer 中所写的那样,只需使用“splat”运算符* 将我上面的代码更正为join(*path_),一切都解决了。

2.) 根据 buran 的建议,您可以使用 pathlib 包,简而言之,它会导致:

from pathlib import PurePath

path_list = list(PurePath(file_path0).parts)
path_list.insert(2, 'new_dir')
file_path1 = PurePath('').joinpath(*path_list)

print(file_path1)
>>> 'dir1/dir2/new_dir/dir3/dir4/file.txt'

【问题讨论】:

  • 我认为这与您的问题没有直接关系,但仅供参考:您无需导入 numpy 即可将值插入列表。 my_list.insert(index, value) 可以单独使用。
  • @Kevin 感谢您的评论,它不会改变结果,但使用您更简单的建议更有意义,所以我更正了我的代码

标签: python path filepath os.path


【解决方案1】:

看看 pathlib.PurePath.parts。它将返回路径的单独组件,您可以在所需位置插入并构建新路径

>>> from pathlib import PurePath
>>> file_path0 = 'dir1/dir2/dir3/dir4/file.txt'
>>> p = PurePath(file_path0)
>>> p.parts
('dir1', 'dir2', 'dir3', 'dir4', 'file.txt')
>>> spam = list(p.parts)
>>> spam.insert(2, 'new_dir')
>>> new_path = PurePath('').joinpath(*spam)
>>> new_path
PurePosixPath('dir1/dir2/new_dir/dir3/dir4/file.txt')

这将与 path 作为 str 以及 pathlib.Path 对象一起使用

【讨论】:

  • 谢谢,这确实是一个可能的解决方案!我对我的问题进行了编辑,将您的代码总结为未来读者的 TLDR
  • 对我来说看起来是最干净的解决方案。也适用于 spam.insert(-1, 'new_dir') 直接在最后一个子文件夹之前插入一个文件夹,因为我需要它。
【解决方案2】:

由于您想在列表上使用 join 来生成路径名,您应该使用“splat”运算符执行以下操作:Python os.path.join() on a list

编辑:您还可以使用 np.array2string 将您的 np 数组和其元素连接成一个字符串,使用“/”作为分隔符参数:https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.array2string.html

希望这会有所帮助。

【讨论】:

  • 问题是关于在另一个字符串中插入一个字符串(这恰好是一个路径,不一定是现有文件,不一定在可访问的磁盘上......)。这与浏览现有目录无关。
  • 您对 np.array2string 的建议以某种方式起作用,但它返回 ['dir1'/'dir2'/'new_dir'/'dir3'/'dir4'/'file.tx']' 形式的字符串,所以我还需要去掉引号。另一方面,您在列表中对os.path.join() 的引用并使用os.path.join(*file_path_list),解决了我的问题中的错误消息并解决了我的问题。如果您将此引用放在帖子的顶部,我可以接受它作为答案。
【解决方案3】:

使用正则表达式的解决方案。正则表达式将创建以下组

[^\/]+   - non-'/' characters(i.e. directory names)
\w+\.\w+ - word characters then '.' then word characters (i.e. file name)
import re

directory_name = 'new_dir'
file_path0 = 'dir1/dir2/dir3/dir4/file.txt'
position = 2

regex = re.compile(r'([^\/]+|\w+\.\w+)')
tokens = re.findall(regex, file_path0)
tokens.insert(position, directory_name)
file_path1 = '/'.join(tokens)

结果:

'dir1/dir2/new_dir/dir3/dir4/file.txt'

【讨论】:

  • 和... Windows?这真的在我看来不像是正则表达式锤子的工作。您可以轻松地在 os.path.sep 上拆分。
【解决方案4】:

就我而言,我知道插入点之前的路径部分(即“根”)。但是,插入点的位置不是恒定的,因为根路径中路径组件的数量可能不同。我使用Path.relative_to() 打破完整路径以产生new_dir 的插入点。

from pathlib import Path

directory_name = Path('new_dir')
root = Path('dir1/dir2/')
file_path0 = Path('dir1/dir2/dir3/dir4/file.txt')

# non-root component of path
chld = file_path0.relative_to(root)
file_path1 = root / directory_name / chld
print(file_path1)

结果:
'dir1/dir2/new_dir/dir3/dir4/file.txt'

【讨论】:

    【解决方案5】:

    我尝试了您的需求:

    directory_name = '/new_dir'
    
    file_path0 = 'dir1/dir2/dir3/dir4/file.txt'
    
    before_the_newpath = 'dir1/dir2'
    
    position = file_path0.split(before_the_newpath)
    
    new_directory = before_the_newpath + directory_name + position[1]
    

    希望对你有帮助。

    【讨论】:

    • 感谢您的回答,它有效。虽然它要求我明确指定before_the_newpath,但它并不是我想要的——我只想给出我想要在路径中放置新元素的位置
    【解决方案6】:

    您的解决方案只有一个缺陷。在路径列表中插入新目录path_.insert(2, 'new_dir')后,您需要调用os.path.join(*path_)来获取新的修改路径。您得到的错误是因为您将 list 作为参数传递给 join 函数,但您必须解压缩它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-18
      • 2023-04-05
      • 2016-01-17
      • 2021-03-21
      • 2011-09-01
      • 2017-02-14
      • 1970-01-01
      相关资源
      最近更新 更多