我正在尝试浏览目录并递归搜索父目录中的三个子目录。这将有效:
def find_files(fPattern, list_to_append):
for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output\CSVs'):
for filename in fnmatch.filter(filenames, fPattern):
list_to_append.append(os.path.join(root, filename))
for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output\No_Bath_CSVS'):
for filename in fnmatch.filter(filenames, fPattern):
list_to_append.append(os.path.join(root, filename))
for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output\Two_Bar_CSVS'):
for filename in fnmatch.filter(filenames, fPattern):
list_to_append.append(os.path.join(root, filename))
return list_to_append
但它相当笨重。我如何os.walk
通过多个子目录而不必硬编码?
答案 0 :(得分:0)
如果你只有r'c:\workspace\Sandbar_Process\csv_output'
中的那3个文件夹,你可以从该文件夹中删除,否则你可以在你的第一次迭代中删除额外的文件夹,就像这样
案例1,没有额外的文件夹
for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output'):
for filename in fnmatch.filter(filenames, fPattern):
list_to_append.append(os.path.join(root, filename))
案例2,额外文件夹
my_folders = ['CSVs', 'No_Bath_CSVS', 'Two_Bar_CSVS']
first = True
for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output'):
if first:
dirnames.clear()
dirnames.extend(my_folders)
first = False
for filename in fnmatch.filter(filenames, fPattern):
list_to_append.append(os.path.join(root, filename))
通过os.walk
对dirnames
收益率的操作会影响您稍后访问子文件夹的方式
查看文档中有关它的内容
os.walk(top, topdown=True, onerror=None, followlinks=False)
当 topdown 为
True
时,调用者可以就地修改 dirnames 列表(可能使用del或slice赋值),{{1}只会递归到名称保留在 dirnames 中的子目录中;这可用于修剪搜索,强制执行特定的访问顺序,甚至可以通知walk()
有关调用者在再次恢复walk()
之前创建或重命名的目录。在topdown为walk()
时修改 dirnames 对walk的行为没有影响,因为在自下而上模式中, dirnames 中的目录是在dirpath本身之前生成的生成。
您也可以像这样重新定义您的功能
False
在这里,您将要使用的文件夹提供给您的功能,然后您只需要使用所需的文件夹进行调用,或者定义另一个使用这些文件夹调用此文件夹的功能,这样您就不会重复代码没有必要。
另外,如果你总是在该文件夹中工作,你可以把它放在像这样的全局变量
中def find_files(fPattern, list_to_append, path):
for root, dirnames, filenames in os.walk(path):
for filename in fnmatch.filter(filenames, fPattern):
list_to_append.append(os.path.join(root, filename))
return list_to_append
并且仅提供相对于该文件夹的文件夹名称,并且当您需要绝对路径来执行某些操作时
WORKING_FOLDER = r'c:\workspace\Sandbar_Process\csv_output'
并定义一个这样的函数,例如
os.path.join(WORKING_FOLDER, foldername)
,例如将其称为
def my_work_in(fPattern, list_to_append, folders):
result = list_to_append
for foldername in folders:
result = find_files(fPattern, result , os.path.join(WORKING_FOLDER, foldername))
return result
当然你应该知道修改你给你的功能的东西通常是不好的做法,所以你的功能应该是
result = my_work_in(fPattern, [], ['CSVs', 'No_Bath_CSVS', 'Two_Bar_CSVS'] )
或更好作为发电机
def find_files(fPattern, path):
result = []
for root, dirnames, filenames in os.walk(path):
for filename in fnmatch.filter(filenames, fPattern):
result.append(os.path.join(root, filename))
return list_to_append
在这两种情况下都没有不必要的修改,您可以将其用作
def find_files(fPattern, path):
for root, dirnames, filenames in os.walk(path):
for filename in fnmatch.filter(filenames, fPattern):
yield os.path.join(root, filename)
为此,生成器版本更好,因为您不会丢失具有中间结果的内存