前言
最近幫忙打雜,需要批量處理文件,因此寫了腳本,不過后來發(fā)現(xiàn)目錄數(shù)量增加了,再一個(gè)個(gè)修改目錄名重新運(yùn)行有的麻煩,于是研究了下python操作文件系統(tǒng)的方法。畢竟python方便移植,不需要像C++那樣需要編譯,對(duì)于VC依賴用戶而言,換操作系統(tǒng)的話還要改下VS的VC運(yùn)行庫的配置。參考我之前一篇C++遍歷目錄的博客Linux和Windows的遍歷目錄下所有文件的方法對(duì)比
相應(yīng)python模塊的方法
思路很簡(jiǎn)單,首先遍歷目錄下所有文件(這里指廣義的文件),然后對(duì)文件進(jìn)行判斷(屬性是否為目錄,后綴是否為xxx)。而python提供的功能更為強(qiáng)大,利用os模塊的walk方法能直接遍歷當(dāng)前目錄和整個(gè)子目錄的文件。
walk(top, topdown=True, onerror=None, followlinks=False)
Directory tree generator.
For each directory in the directory tree rooted at top (including top
itself, but excluding '.' and '..'), yields a 3-tuple
dirpath, dirnames, filenames
dirpath is a string, the path to the directory. dirnames is a list of
the names of the subdirectories in dirpath (excluding '.' and '..').
filenames is a list of the names of the non-directory files in dirpath.
Note that the names in the lists are just names, with no path components.
To get a full path (which begins with top) to a file or directory in
dirpath, do os.path.join(dirpath, name).
后面3個(gè)自定義選項(xiàng)暫時(shí)可以不考慮(詳細(xì)可以參考help(os.walk)),top即頂層目錄,walk返回一個(gè)生成器,迭代每個(gè)生成器會(huì)返回一個(gè)三元組(dirpath, dirnames, filenames),依次代表目錄名,該目錄下的目錄類型文件列表(不包括.和..),該目錄下的非目錄類型文件列表。
>>> import os
>>> for parent, dirnames, filenames in os.walk('./cpp'):
... for dirname in dirnames:
... print('[DIR]', dirname)
... for filename in filenames:
... print('[FILE]', filename)
... break
...
[DIR] string
[DIR] lists
[DIR] bitree
[DIR] reference
[DIR] threads
[FILE] test.cc
[FILE] binary_tree.c
[FILE] shared_ptr.cc
[FILE] get_arraysize.cc
[FILE] subset_all.cc
[FILE] bind_demo.cc
[FILE] a.out
[FILE] binary_tree.cpp
上述代碼即遍歷當(dāng)前目錄的所有文件并打印文件名,若去掉break則可以深層次遍歷所有子目錄。
至于后續(xù)操作則借用下列方法即可
- os.listdir(path=None)
獲取目錄下所有文件名,若未指定path則默認(rèn)路徑為當(dāng)前目錄。類似Linux下的ls命令 - os.path.join(a, *p)
用'/'或者其他連接符(比如windows下為'\')將路徑列表連接起來 - os.path.isdir(s)
s為完整路徑,若s為目錄類型則返回True - os.path.splitext(p)
p為文件路徑(不一定是完整路徑),返回二元組(root, ext),ext即后綴
函數(shù)式編程實(shí)現(xiàn)
最近剛接觸了下python對(duì)函數(shù)式編程的支持,代碼確實(shí)優(yōu)雅不少,對(duì)性能沒有嚴(yán)格要求的情景下這種風(fēng)格的代碼看起來非常舒服。
def subdir_list(dirname):
"""獲取目錄下所有子目錄名
@param dirname: str 目錄的完整路徑
@return: list(str) 所有子目錄完整路徑組成的列表
"""
return list(filter(os.path.isdir,
map(lambda filename: os.path.join(dirname, filename),
os.listdir(dirname))))
def file_list(dirname, ext='.csv'):
"""獲取目錄下所有特定后綴的文件
@param dirname: str 目錄的完整路徑
@param ext: str 后綴名, 以點(diǎn)號(hào)開頭
@return: list(str) 所有子文件名(不包含路徑)組成的列表
"""
return list(filter(
lambda filename: os.path.splitext(filename)[1] == ext,
os.listdir(dirname)))
話說這種)))))...風(fēng)格的代碼自從N年前學(xué)autolisp時(shí)才寫過,不知道縮進(jìn)風(fēng)格對(duì)不對(duì),先這樣吧。