generator中使用recursive

bypy项目的download是下载一个目录结构里的所有文件,用了递归,代码如下

    def _walk_proceed_remote_dir(self, remotepath, proceed, args = None, skip_remote_only_dirs = False, recursive = True):
        result = const.ENoError
        for walk in self._walk_remote_dir(remotepath, remotepath, args, skip_remote_only_dirs, recursive):
            subresult = proceed(*walk)
            if subresult != const.ENoError:
                result = subresult
        return result
    def _walk_remote_dir(self, remotepath, remoterootpath, args = None, skip_remote_only_dirs = False, recursive = True):
        dirjs = []
        filejs = []
        listStart = 0
        # https://github.com/houtianze/bypy/issues/285
        while True:
            pars = {
                'method' : 'list',
                'path' : remotepath,
                'by' : 'name',
                'order' : 'asc',
                'limit' : '{}-{}'.format(listStart, listStart + const.MaxListEntries)}
            # Python parameters are by-reference and mutable, so they are 'out' by default
            result = self._get(pcsurl + 'file', pars, self._walk_proceed_remote_dir_act, (dirjs, filejs))
            if len(dirjs) + len(filejs) - listStart < const.MaxListEntries:
                break
            listStart += const.MaxListEntries
        yield [result, remotepath, dirjs, filejs, args]
        if result == const.ENoError:
            self.pd("Remote dirs: {}".format(dirjs))
            self.pd("Remote files: {}".format(filejs))
            if recursive:
                for dirj in dirjs:
                    crpath = dirj['path'] # crpath - current remote path
                    if skip_remote_only_dirs and remoterootpath != None and \
                        self._local_dir_contents.get(posixpath.relpath(crpath, remoterootpath)) == None:
                        self.pd("Skipping remote-only sub-directory '{}'.".format(crpath))
                        continue

                    # http://stackoverflow.com/a/8991864/404271
                    # for Python 3.3+, "yield from" reads better
                    for y in self._walk_remote_dir(crpath, remoterootpath, args, skip_remote_only_dirs):
              yield y

注意每次循环执行_walk_remote_dir 相当于iterator 执行next(),从上次的yield 执行到下一个yield之间的代码。在_walk_remote_dir里第一个yield不在循环体里,第二个yield在循环体里面。

https://stackoverflow.com/questions/8991840/recursion-using-yield/8991864#8991864

posted @ 2023-01-11 01:37  zjhgx  阅读(28)  评论(0编辑  收藏  举报