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
喜欢艺术的码农