使用 Python 遍历目录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19587118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Iterating through directories with Python
提问by Wolf
I need to iterate through the subdirectories of a given directory and search for files. If I get a file I have to open it and change the content and replace it with my own lines.
我需要遍历给定目录的子目录并搜索文件。如果我得到一个文件,我必须打开它并更改内容并用我自己的行替换它。
I tried this:
我试过这个:
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()
but I am getting an error. What am I doing wrong?
但我收到一个错误。我究竟做错了什么?
采纳答案by ChrisProsser
The actual walk through the directories works as you have coded it. If you replace the contents of the inner loop with a simple print
statement you can see that each file is found:
实际浏览目录的工作方式与您编写的代码相同。如果用一个简单的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)
If you still get errors when running the above, please provide the error message.
如果在运行上述程序时仍然出现错误,请提供错误消息。
Updated for Python3
为 Python3 更新
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))
回答by joelostblom
Another way of returning all files in subdirectories is to use the pathlib
module, introduced in Python 3.4, which provides an object oriented approach to handling filesystem paths (Pathlib is also available on Python 2.7 via the pathlib2 module on PyPi):
返回子目录中所有文件的另一种方法是使用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()]
Since Python 3.5, the glob
module also supports recursive file finding:
从 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)]
The file_list
from either of the above approaches can be iterated over without the need for a nested loop:
在file_list
从任一上述方法可被遍历,而不需要一个嵌套循环:
for f in file_list:
print(f) # Replace with desired operations
回答by CONvid19
As of 2020, glob.iglob(path/**, recursive=True)
seems the most pythonicsolution, i.e.:
截至2020 年,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)
Output:
输出:
/pardadox-music/modules/her1.mod
/pardadox-music/modules/her2.mod
...
Notes:
1 - glob.iglob
注释:
1 - glob.iglob
glob.iglob(pathname, recursive=False)
Return an iterator which yields the same values as
glob()
without actually storing them all simultaneously.
glob.iglob(pathname, recursive=False)
返回一个迭代器,它产生相同的值,
glob()
而不实际同时存储它们。
2 - If recursive is True
, the pattern '**'
will match any files and
zero or more directories
and subdirectories
.
2 - 如果递归是True
,模式'**'
将匹配任何文件和零个或多个directories
和subdirectories
。
3 - If the directory contains files starting with?.
they won't be matched by default. For example, consider a directory containing?card.gif
?and .card.gif
:
3 - 如果目录包含以? .
默认情况下它们不会匹配。例如,考虑一个包含? card.gif
?和.card.gif
:
>>> import glob
>>> glob.glob('*.gif') ['card.gif']
>>> glob.glob('.c*')['.card.gif']
4 - You can also use rglob(pattern)
,
which is the same as calling?glob()
?with **/
added in front of the given relative?pattern.
4 - 您也可以使用rglob(pattern)
,这与调用相同吗?glob()
?with**/
添加在给定的相对模式之前。