【问题标题】:Adding another suffix to a path that already has a suffix with pathlib将另一个后缀添加到已经具有 pathlib 后缀的路径
【发布时间】:2018-03-20 09:31:41
【问题描述】:

我将一些旧的 Python 代码转换为使用 pathlib 而不是 os.path 进行大多数与路径相关的操作,但我最终遇到了以下问题:我需要向已经有扩展名的路径添加另一个扩展名(不是替换它)。使用os.path,由于我们只是在操作字符串,解决方案是添加带有字符串操作的扩展:

newpath = path + '.res'

它不适用于pathlib.Path,因为它不允许连接任意字符。我能找到的最接近的是:

newpath = path.with_suffix(path.suffix + '.res')

这看起来像是一种解决方法,因为它最后仍然使用字符串添加。而且它有一个新的陷阱,因为我一开始忘记处理已经有几个扩展并且你想添加一个新的情况,导致下面的代码恢复旧的行为:

newpath = path.with_suffix(''.join(path.suffixes) + '.res')

现在感觉既不简洁也不干净,因为它使用越来越多的字符串操作来实现旧的行为,而不是纯粹的路径操作。 Path.suffixes 存在的事实意味着库的开发人员考虑了文件可以具有多个扩展名的情况,但我找不到简单地将新扩展名添加到路径的方法。有没有更惯用的方式来实现相同的行为?

编辑:实际上path.with_suffix(path.suffix + '.res') 足以处理已经有多个文件扩展名的情况,即使它对我来说并不是很明显。

【问题讨论】:

  • 在发布我的答案后才看到您的编辑......这似乎也是一个很好的解决方案
  • 似乎没有比您已经拥有的单线更好的答案了。 pathlib 似乎有一些非常烦人的致命缺陷,使其比普通字符串更难使用——例如,如果你想在你的方法中添加后缀 _foo.res,你会得到 ValueError: Invalid suffix,因为它没有不要以点开头!
  • 应该选择一个答案...
  • @MadPhysicist 如果我认为有一个好的答案,我会这样做,但正如提到pathlib3x 的答案所证明的那样,标准库中没有一个干净的解决方案(而且我没有想要为整个库添加一个新的依赖项),虽然一些提议的替代方案是有效的,但没有一个让人感到满意。我宁愿让大众选择他们最喜欢的答案。
  • @Morwenn。同时,您的问题在未回答的队列中徘徊,而一些倒霉的人缺少他们的 15 分

标签: python python-3.x pathlib


【解决方案1】:

我发现以下内容比已经给出的答案更令人满意:

new_path = path.parent / (path.name + '.suffix')

【讨论】:

  • 光荣。一直在为此苦苦挣扎 - 我没有想到括号。
  • 更加精简的版本:new_path = path.parent / f"{path.name}.suffix"
【解决方案2】:

Path 看起来不像是在原地修改(你不能更改 .parts[-1] 目录或更改 .suffixes 等),但这并不意味着你需要求助于任何太令人讨厌的东西.以下工作很好,即使它不像我想要的那样优雅:

new_path = path.with_suffix(path.suffix + new_suffix)

其中path 是您的原始路径变量,new_suffix 是带有新后缀/扩展名的字符串(包括前导“.”)

【讨论】:

  • 如果你要写出这两个扩展,写成new_path = path.with_suffix(new_suffix)可能会更规范
  • 您的答案将替换后缀,而不是添加它
  • @ImanolUr 我认为“new_suffix”会包含所有需要的内容。查看编辑后的代码以获得更直观的答案。
  • 但是...path.parent / path.name 完全等同于原始的path 那么它与OP 的path.with_suffix(path.suffix + '.res') 有什么不同呢?
【解决方案3】:

您可以将您的Path 转换为字符串,然后添加新的扩展名并转换回Path

from pathlib import Path
first = Path("D:/user/file.xy")
print(first)
second = Path(str(first)+".res")
print(second)

【讨论】:

  • 你也可以猴子补丁:Path.__add__ = lambda self, rhs: Path(str(self) + rhs)
【解决方案4】:

您可以使用 pathlib3x - 它提供了最新的(在撰写此答案 Python 3.10.a0 之日)Python 3.6 或更高版本的 Python pathlib 的反向移植,以及一些额外的功能,如 append_suffix

>>> python -m pip install pathlib3x

>>> import pathlib3x as pathlib

>>> pathlib.Path('some_path').append_suffix('.ext')
PosixPath('some_path.ext')
>>> pathlib.Path('some_path.ext.ext2').append_suffix('.ext3')
PosixPath('some_path.ext.ext2.ext3')


您可以在githubPyPi 上找到它


免责声明:我是 pathlib3x 库的作者。

【讨论】:

  • 你知道这个 repo 将来会如何维护吗?
  • 酷,现在这是我想要的标准库中的东西:o
  • @Dash:只要我活着,它就会一直维护——然后你可以接管 ;-) 因为我每天都在使用它...
  • @Morwenn 这是我这样做的原因之一——一方面很明显,开发人员不想弄乱标准库,另一方面我想以某种方式添加有用的功能即兼容并符合标准库的风格。只是为了让我自己的代码更具可读性和更少冗长。
【解决方案5】:

我认为这会更好,因为您只想用任意字符串扩展当前路径。

old_path = Path("/the/old/path.foo")  # "/the/old/path.foo"
new_path = Path(f"{old_path}.bar")    # "/the/old/path.foo.bar"

【讨论】:

    【解决方案6】:

    如果您想附加文件名,但不更改扩展名,这可行

    matfile2 = pathlib.Path.joinpath(matfile.parent, matfile.stem+' insert'+matfile.suffix)
    

    【讨论】:

      【解决方案7】:

      下面的代码应该以一种非常动态的方式做你想做的事情。

      from pathlib import Path
      import time
      
      p = Path('.')
      p = p / '..' / 'Python' / 'Files' / 'Texts_to_read' / 'a_text_file'
      
      new_p = str(p).split('\\')
      
      new_suffix = '.txt'
      
      new_p[-1] = new_p[-1] + new_suffix
      
      p = Path('.')
      
      for x in new_p:
          p = p / x
      
      print(new_p)
      
      print(p)
      print(str(p))
      
      time.sleep(5)
      

      在这种情况下可以使用普通的字符串操作是一件好事,因为它增加了对所需文件路径的大量控制,而不需要大量的新函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-29
        • 2019-03-07
        • 2017-05-08
        • 1970-01-01
        • 2015-06-14
        相关资源
        最近更新 更多