使用Python迭代目录

Wol*_*olf 135 python directory

我需要遍历给定目录的子目录并搜索文件.如果我得到一个文件,我必须打开它并更改内容并用我自己的行替换它.

我试过这个:

import os

rootdir ='C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        f=open(file,'r')
        lines=f.readlines()
        f.close()
        f=open(file,'w')
        for line in lines:
            newline = "No you are not"
            f.write(newline)
        f.close()
Run Code Online (Sandbox Code Playgroud)

但是我收到了一个错误.我究竟做错了什么?

Chr*_*ser 269

实际遍历目录的过程与编码时一样.如果使用简单print语句替换内部循环的内容,则可以看到找到每个文件:

import os
rootdir = 'C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        print os.path.join(subdir, file)
Run Code Online (Sandbox Code Playgroud)

如果在运行上述操作时仍然出现错误,请提供错误消息.

  • 嗨!请记住,python 3中的“ print”需要括号,否则会返回语法错误。希望这可以帮助! (2认同)

joe*_*lom 11

返回子目录中所有文件的另一种方法是使用Python 3.4中引入pathlib模块,模块提供了一种面向对象的方法来处理文件系统路径(Pathlib也可以通过PyPi上的pathlib2模块在 Python 2.7 上使用):

from pathlib import Path

rootdir = Path('C:/Users/sid/Desktop/test')
# Return a list of regular files only, not directories
file_list = [f for f in rootdir.glob('**/*') if f.is_file()]

# For absolute paths instead of relative the current dir
file_list = [f for f in rootdir.resolve().glob('**/*') if f.is_file()]
Run Code Online (Sandbox Code Playgroud)

从Python 3.5开始,该glob模块还支持递归文件查找:

import os
from glob import iglob

rootdir_glob = 'C:/Users/sid/Desktop/test/**/*' # Note the added asterisks
# This will return absolute paths
file_list = [f for f in iglob('**/*', recursive=True) if os.path.isfile(f)]
Run Code Online (Sandbox Code Playgroud)

file_list从任一上述方法可被遍历,而不需要一个嵌套循环:

for f in file_list:
    print(f) # Replace with desired operations
Run Code Online (Sandbox Code Playgroud)

  • Python 3.6 在这里更可取的是什么? (2认同)

Ped*_*ito 7

截至2019年glob.iglob(path/**, recursive=True)似乎是最pythonic的解决方案,即:

import glob, os

for filename in glob.iglob('/pardadox-music/**', recursive=True):
    if os.path.isfile(filename): # filter dirs
        print(filename)
Run Code Online (Sandbox Code Playgroud)

输出:

/pardadox-music/modules/her1.mod
/pardadox-music/modules/her2.mod
...
Run Code Online (Sandbox Code Playgroud)

注意:
1- glob.iglob

glob.iglob(pathname, recursive=False)

返回一个迭代器,该迭代器产生的值与glob()实际没有同时存储它们的值相同。

2-如果是递归的True,则模式'**'将匹配任何文件以及零个或多个directoriessubdirectories

3-如果目录包含以开头的文件,  .则默认情况下将不匹配它们。例如,考虑包含card.gif 和的目录  .card.gif

>>> import glob. 
>>> glob.glob('*.gif') ['card.gif'] 
>>> glob.glob('.c*')['.card.gif']
Run Code Online (Sandbox Code Playgroud)

  • 这个 _pythonic_ 解决方案不会列出隐藏文件(又名点文件),而接受的解决方案会列出。 (2认同)
  • @ashrasmun你提到的在https://docs.python.org/3/library/glob.html中有很好的解释 (2认同)