代码之家  ›  专栏  ›  技术社区  ›  fish2000

递归目录列表/分析函数似乎没有正确递归

  •  0
  • fish2000  · 技术社区  · 14 年前

    我编写了一个简单的python脚本来遍历给定的目录,并将找到的所有文件后缀列表。输出如下:

    OTUS-ASIO:face fish$ sufs
    
    >>>         /Users/fish/Dropbox/ost2/face (total 194)
    ===                    1       1      -
    ===                  css      16      -----
    ===                  gif      14      -----
    ===                 html      12      ----
    ===                  icc      87      --------------------------
    ===                  jpg       3      -
    ===                   js      46      --------------
    ===                  png       3      -
    ===                  zip       2      -
    

    …如果这些值是正确的,那就太好了。它们不是。下面是当我在上面列出的目录的子目录中运行它时发生的情况:

    OTUS-ASIO:face fish$ cd images/
    OTUS-ASIO:images fish$ sufs
    
    >>>         /Users/fish/Dropbox/ost2/face/images (total 1016)
    ===                  JPG       3      -
    ===                  gif      17      -
    ===                  ico       1      -
    ===                 jpeg       1      -
    ===                  jpg     901      --------------------------
    ===                  png      87      ---
    

    …它似乎只降低了一个目录级别。运行一级以上的脚本根本没有得到“jpeg”后缀,似乎错过了一个良好的898JPG文件。

    本文讨论的脚本如下:

    #!/usr/bin/env python
    # encoding: utf-8
    """
    getfilesuffixes.py
    
    Created by FI$H 2000 on 2010-10-15.
    Copyright (c) 2010 OST, LLC. All rights reserved.
    """
    
    import sys, os, getopt
    
    help_message = '''
    Prints a list of all the file suffixes found in each DIR, with counts.
    Defaults to the current directory wth no args.
    
    $ %s DIR [DIR DIR etc ...]
    ''' % os.path.basename(__file__)
    
    dirs = dict()
    skips = ('DS_Store','hgignore')
    
    class Usage(Exception):
        def __init__(self, msg):
            self.msg = msg
    
    def getmesomesuffixes(rootdir, thisdir=None):
        if not thisdir:
            thisdir = rootdir
    
        for thing in [os.path.abspath(h) for h in os.listdir(thisdir)]:
            if os.path.isdir(thing):
                getmesomesuffixes(rootdir), thing)
            else:
                if thing.rfind('.') > -1:
                    suf = thing.rsplit('.').pop()
                    dirs[rootdir][suf] = dirs[rootdir].get(suf, 0) + 1
        return
    
    def main(argv=None):
        if argv is None:
            argv = sys.argv
        try:
            try:
                opts, args = getopt.getopt(argv[1:], "h", ["help",])
            except getopt.error, msg:
                raise Usage(msg)
            for option, value in opts:
                if option == "-v":
                    verbose = True
                if option in ("-h", "--help"):
                    raise Usage(help_message)
    
            if len(args) == 0:
                args.append(os.getcwd())
    
            for durr in [os.path.abspath(arg) for arg in args]:
                if os.path.isdir(durr):
                    dirs[durr] = dict()
    
            for k, v in dirs.items():
                getmesomesuffixes(k)
    
            print ""
    
            for k, v in dirs.items():
                sufs = v.items()
                sufs.sort()
    
                maxcount = reduce(lambda fs, ns: fs > ns and fs or ns, map(lambda t: t[1], sufs), 1)
                mincount = reduce(lambda fs, ns: fs < ns and fs or ns, map(lambda t: t[1], sufs), 1)
                total = reduce(lambda fs, ns: fs + ns, map(lambda t: t[1], sufs), 0)
                print ">>>\t\t\t%s (total %s)" % (k, total)
    
                for suf, sufcount in sufs:
                    try:
                        skips.index(suf)
                    except ValueError:
                        print "===\t\t\t%12s\t %3s\t  %s" % (suf, sufcount, "-" * (int(float(float(sufcount) / float(maxcount)) * 25) + 1))
                print ""
    
    
        except Usage, err:
            print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg)
            print >> sys.stderr, "\t for help use --help"
            return 2
    
    
    if __name__ == "__main__":
        sys.exit(main())
    

    似乎 getmesomesuffixes() 巧妙地不做我想做的事。我不想问这样一个烦人的问题,但如果有人能发现我一次又一次快速地犯下的业余时间错误,那我就不会有太大的挫折感了。

    2 回复  |  直到 11 年前
        1
  •  3
  •   pyfunc    14 年前

    是的,如果你用OS.walk,你会过得更好吗?

    for root, dirs, files in os.walk(basedir):
        ... do you stuff ..
    

    参见中的示例

    也可以查看os.path.splitext(path),这是查找文件类型的更好方法。

    >>> os.path.splitext('/d/c/as.jpeg')
    ('/d/c/as', '.jpeg')
    >>> 
    

    这两者都应该简化您的代码。

        2
  •  1
  •   hughdbrown    14 年前
    import os
    import os.path
    from collections import defaultdict
    
    def foo(dir='.'):
        d = defaultdict(int)   
        for _, _, files in os.walk(dir):
            for f in files:
                d[os.path.splitext(f)[1]] += 1
        return d
    
    if __name__ == '__main__':
        d = foo()
        for k, v in sorted(d.items()):
            print k, v
    
    推荐文章