【问题标题】:Efficient way of creating recursive paths Python创建递归路径Python的有效方法
【发布时间】:2010-10-30 23:32:21
【问题描述】:

我需要一个简单的函数来在 Python 中创建一个父路径可能存在也可能不存在的路径。

从 python 文档中,如果父母之一存在,os.makedirs 将失败。

我已经编写了以下方法,它可以根据需要创建尽可能多的子目录。

这看起来有效率吗?

def create_path(path):
    import os.path as os_path
    paths_to_create = []
    while not os_path.lexists(path):
        paths_to_create.insert(0, path)
        head,tail = os_path.split(path)
        if len(tail.strip())==0: # Just incase path ends with a / or \
            path = head
            head,tail = os_path.split(path)
        path = head

    for path in paths_to_create:
        os.mkdir(path)

【问题讨论】:

    标签: python path operating-system


    【解决方案1】:

    “来自 python 文档 os.makedirs 将失败,如果其中一个父母存在。”

    不,如果目录本身已经存在,os.makedirs 将失败。如果仅存在任何父目录,它不会失败。

    【讨论】:

    • 这两句话有矛盾吗?
    • @AlanSha:是的,它们相互矛盾。引用来自问题并包含误解。然后我的评论试图纠正这种误解并解释真正发生的事情。
    【解决方案2】:

    这是我的看法,它让系统库完成所有路径争论。除了已经存在的目录之外的任何错误都会传播。

    import os, errno
    
    def ensure_dir(dirname):
        """
        Ensure that a named directory exists; if it does not, attempt to create it.
        """
        try:
            os.makedirs(dirname)
        except OSError, e:
            if e.errno != errno.EEXIST:
                raise
    

    【讨论】:

    【解决方案3】:

    草稿:

    import os
    
    
    class Path(str):
        """
        A helper class that allows easy contactenation
        of path components, creation of directory trees,
        amongst other things.
        """  
        @property
        def isdir(self):
            return os.path.isdir(self)
    
        @property
        def isfile(self):
            return os.path.isfile(self)
    
        def exists(self):
            exists = False
            if self.isfile:
                try:
                    f = open(self)
                    f.close()
                    exists = True
                except IOError:
                    exists = False
            else:
                return self.isdir
            return exists
    
        def mktree(self, dirname):
            """Create a directory tree in this directory."""
            newdir = self + dirname
            if newdir.exists():
                return newdir
            path = dirname.split('/') or [dirname]
            current_path = self + path.pop(0)
            while True:
                try:
                    os.mkdir(current_path)
                except OSError as e:
                    if not e.args[0] == 17:
                        raise e
                    current_path = current_path + path.pop(0)
                    continue
                if len(path) == 0:
                    break
            return current_path
    
        def up(self):
            """
            Return a new Path object set a the parent
            directory of the current instance.
            """
            return Path('/'.join(self.split('/')[:-1]))
    
        def __repr__(self):
            return "<Path: {0}>".format(self)
    
        def __add__(x, y):
            return Path(x.rstrip('/') + '/' + y.lstrip('/'))
    

    【讨论】:

      【解决方案4】:

      对于 python ( >=3.4.1 ),os.makedirs 有 exists_ok 参数。

      如果 exists_ok 为 False(默认值),如果目标 目录已存在。

      所以如果你使用 like exists_ok=True ,递归目录创建不会有任何问题。

      注意:exist_ok 是 python 3.2 自带的,但存在一个 bug 即使您设置为 True,也会引发异常。所以尝试使用 python >= 3.4.1(该版本已修复)

      【讨论】:

        【解决方案5】:

        试试这个代码,它检查路径是否存在直到 n 子目录级别,如果不存在则创建目录。

        def pathtodir(path):
        if not os.path.exists(path):
            l=[]
            p = "/"
            l = path.split("/")
            i = 1
            while i < len(l):
                p = p + l[i] + "/"
                i = i + 1
                if not os.path.exists(p):
                    os.mkdir(p, 0755)
        

        【讨论】:

          【解决方案6】:

          这是一个旧线程,但我对所提供的解决方案并不满意,因为它们对于简单的任务来说大多过于复杂。

          从库中的可用函数中,我相信我们能做的最干净的是:

          os.path.isdir("mydir") or os.makedirs("mydir")
          

          【讨论】:

            【解决方案7】:

            我在研究一种在项目目录中制作简单目录树的方法时发现了这个问题。

            我对 Python 有点陌生,当数据结构变得过于复杂(即嵌套)时,我会遇到困难。在我的大脑的思维导图中,跟踪小型迭代列表要容易得多,所以我想出了两个非常基本的定义来帮助我创建目录树。

            该示例使用四个对象来创建一棵树:

            1. 根目录路径 = PROJECT_HOME
            2. 主路径 = 主路径(如果不存在则创建,不会被覆盖)
            3. 将进入 home = 分支的目录名称的可迭代(在 home 内部创建,不会被覆盖)
            4. 映射到分支 = 叶子的键控迭代字典(在每个映射分支内部创建的每个值,不会被覆盖)
            5. 如果任何目录存在,它不会被覆盖,错误会静默传递。

              import os
              from os.path import join as path_join
              import errno
              
              def make_node(node):
                  try:
                      os.makedirs(node)
                  except OSError, e:
                      if e.errno != errno.EEXIST:
                          raise
              
              
              def create_tree(home, branches, leaves):
                  for branch in branches:
                      parent = path_join(home, branch)
                      make_node(parent)
                      children = leaves.get(branch, [])
                      for child in children:
                          child = os.path.join(parent, child)
                          make_node(child)
              
              if __name__ == "__main__":
                  try:  # create inside of PROJECT_HOME if it exists
                      PROJECT_HOME = os.environ['PROJECT_HOME']
                  except KeyError:  # otherwise in user's home directory
                      PROJECT_HOME = os.expanduser('~')
              
                  home = os.path.join(PROJECT_HOME, 'test_directory_tree')
                  create_tree(home, branches=[], leaves={})
              
                  branches = (
                      'docs',
                      'scripts',
                  )
                  leaves = (
                      ('rst', 'html', ),
                      ('python', 'bash', )
                  )
                  leaves = dict(list(zip(branches, leaves)))
                  create_tree(home, branches, leaves)
              
                  python_home = os.path.join(home, 'scripts', 'python')
                  branches = (
                      'os',
                      'sys',
                      'text_processing',
                  )
                  leaves = {}
                  leaves = dict(list(zip(branches, leaves)))
                  create_tree(python_home, branches, leaves)
              
                  after_thought_home = os.path.join(home, 'docs', 'after_thought')
                  branches = (
                      'child_0',
                      'child_1',
                  )
                  leaves = (
                      ('sub_0', 'sub_1'),
                      (),
                  )
                  leaves = dict(list(zip(branches, leaves)))
                  create_tree(after_thought_home, branches, leaves)
              

            此示例创建的目录树如下所示:

                dev/test_directory_tree/
                ├── docs
                │   ├── after_thought
                │   │   ├── child_0
                │   │   │   ├── sub_0
                │   │   │   └── sub_1
                │   │   └── child_1
                │   ├── html
                │   └── rst
                └── scripts
                    ├── bash
                    └── python
                        ├── os
                        ├── sys
                        └── text_processing
            

            【讨论】:

              【解决方案8】:

              This code 将使用递归函数调用生成具有给定深度和宽度的目录树:

              #!/usr/bin/python2.6
              
              import sys
              import os
              
              def build_dir_tree(base, depth, width):
                  print("Call #%d" % depth)
                  if depth >= 0:
                      curr_depth = depth
                      depth -= 1
                      for i in xrange(width):
                              # first creating all folder at current depth
                              os.makedirs('%s/Dir_#%d_level_%d' % (base, i, curr_depth))
                      dirs = os.walk(base).next()[1]
                      for dir in dirs:
                              newbase = os.path.join(base,dir)
                              build_dir_tree(newbase, depth, width)
                  else:
                      return
              
              if not sys.argv[1:]:
                      print('No base path given')
                      sys.exit(1)
              
              print('path: %s, depth: %d, width: %d' % (sys.argv[1], int(sys.argv[2]), int(sys.argv[3])))
              build_dir_tree(sys.argv[1], int(sys.argv[2]), int(sys.argv[3]))
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-03-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-02-17
                • 1970-01-01
                • 2022-09-27
                • 1970-01-01
                相关资源
                最近更新 更多