【问题标题】:How to move up n directories in Pythonic way?如何以 Pythonic 方式向上移动目录?
【发布时间】:2019-08-26 06:13:01
【问题描述】:

我正在寻找一种 Python 方式来从给定目录中向上移动 n 目录。

假设我们有示例路径/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data。如果我们要向上移动n=2 目录,我们应该最终到达/data/python_env/lib/python3.6/site-packages

以下工作可向上移动n 目录:

up_n = lambda path, n: '/'.join(path.split('/')[:-n])

但是,它的可读性不是很好,并且对于 Windows 机器上的路径会失败。本质上,感觉不是一个非常pythonic的解决方案。

是否有更好、更 Pythonic 的解决方案,可能使用 os 模块?

【问题讨论】:

  • 我觉得你应该使用Path模块,更好地避免硬编码取决于操作系统!

标签: python python-3.x operating-system


【解决方案1】:

可以使用标准库的pathlib模块:

from pathlib import Path

path = Path('/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data')

levels_up = 2
print(path.parents[levels_up-1])
# /data/python_env/lib/python3.6/site-packages

【讨论】:

  • 我觉得这是最好的解决方案:跨平台,易于阅读且不涉及n 调用os.path。但是,由于pathlib 仅在 Python 3.4+ 的标准库中,因此在旧版 python 上阅读此内容的用户应考虑安装 pathlibpip
【解决方案2】:

os.path.dirname 迭代怎么样:

import os

s = "/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data"
for _ in range(2):
    s = os.path.dirname(s)

print(s)

打印:

/data/python_env/lib/python3.6/site-packages

【讨论】:

    【解决方案3】:

    您可以为此使用 python os.path 模块:

    >>> p = '/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data'
    >>> os.path.normpath(os.path.join(p, "..", ".."))
    '/data/python_env/lib/python3.6/site-packages'
    

    或者泛指n

    os.path.normpath(os.path.join(*([p]+[".."]*n)))
    

    这样,您不必关心使用的是 Windows \ 还是 UNIX /。 Python 应该能很好地处理这个问题。而且,你有一个单线。

    【讨论】:

    • 我认为他们要求它是 more 可读而不是 less ;)
    • @Chris_Rands 是对的:这不是特别可读。话虽如此,我当然不认为它比我最初的解决方案更具可读性。无论如何,受这个解决方案的启发,我想出了os.path.abspath(os.path.join(p, "../"*n)),我认为这是一个边际改进。
    【解决方案4】:

    对此的一种解决方案可以利用.. 是父目录的简写形式。所以,使用pathlib 你可以写

    from pathlib import Path
    up_n = lambda orig, n: Path(orig).joinpath('/'.join(['..']*n))
    

    【讨论】:

      【解决方案5】:

      对于 Python 3.4+,pathlib 可能是最佳选择。

      也就是说,以下内容也适用于旧版本(包括 Python 2.x):

      import os
      
      def up_n(path, n):
          components = os.path.normpath(path).split(os.sep)
          return os.sep.join(components[:-n])
      
      if __name__ == '__main__':
          path = '/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data'
          result = up_n(path, 2)
          print(result)  # -> \data\python_env\lib\python3.6\site-packages
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-23
        • 2010-12-06
        • 2011-05-09
        • 2017-05-03
        • 1970-01-01
        • 1970-01-01
        • 2013-06-10
        • 1970-01-01
        相关资源
        最近更新 更多