Làm cách nào tôi có thể liệt kê tất cả các tệp của một thư mục trong Python và thêm chúng vào một list
?
Làm cách nào tôi có thể liệt kê tất cả các tệp của một thư mục trong Python và thêm chúng vào một list
?
Câu trả lời:
os.listdir()
sẽ giúp bạn có mọi thứ trong một thư mục - tệp và thư mục .
Nếu bạn chỉ muốn các tệp, bạn có thể lọc phần này xuống bằng cách sử dụng os.path
:
from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
hoặc bạn có thể sử dụng os.walk()
mà sẽ mang lại hai danh sách cho mỗi thư mục đó thăm - chia tách thành các file và dirs cho bạn. Nếu bạn chỉ muốn thư mục trên cùng, bạn chỉ có thể phá vỡ lần đầu tiên nó mang lại
from os import walk
f = []
for (dirpath, dirnames, filenames) in walk(mypath):
f.extend(filenames)
break
(_, _, filenames) = walk(mypath).next()
(nếu bạn tự tin rằng cuộc đi bộ sẽ trả lại ít nhất một giá trị, điều đó nên.)
f.extend(filenames)
không thực sự tương đương với f = f + filenames
. extend
sẽ sửa đổi f
tại chỗ, trong khi thêm sẽ tạo một danh sách mới trong một vị trí bộ nhớ mới. Điều này có nghĩa extend
là thường hiệu quả hơn +
, nhưng đôi khi có thể dẫn đến nhầm lẫn nếu nhiều đối tượng giữ các tham chiếu đến danh sách. Cuối cùng, đáng chú ý f += filenames
là tương đương với f.extend(filenames)
, không f = f + filenames
.
_, _, filenames = next(walk(mypath), (None, None, []))
(_, _, filenames) = next(os.walk(mypath))
Tôi thích sử dụng glob
mô-đun, vì nó phù hợp với mô hình và mở rộng.
import glob
print(glob.glob("/home/adam/*.txt"))
Nó sẽ trả về một danh sách với các tệp được yêu cầu:
['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]
/home/user/foo/bar/hello.txt
, sau đó, nếu chạy trong thư mục foo
, glob("bar/*.txt")
sẽ trở lại bar/hello.txt
. Có những trường hợp khi bạn thực tế muốn đường dẫn đầy đủ (tức là tuyệt đối); đối với những trường hợp đó, hãy xem stackoverflow.com/questions/51520/ Cách
glob.glob("*")
sẽ.
x=glob.glob("../train/*.png")
sẽ cho tôi một mảng các đường dẫn của tôi, miễn là tôi biết tên của thư mục. Thật tuyệt!
Nhận danh sách các tệp với Python 2 và 3
os.listdir()
Cách nhận tất cả các tệp (và thư mục) trong thư mục hiện tại (Python 3)
Sau đây, là các phương pháp đơn giản để chỉ truy xuất các tệp trong thư mục hiện tại, sử dụng os
và listdir()
hàm, trong Python 3. Khám phá thêm, sẽ trình bày cách trả lại các thư mục trong thư mục, nhưng bạn sẽ không có tệp trong thư mục con, cho bạn có thể sử dụng đi bộ - thảo luận sau).
import os
arr = os.listdir()
print(arr)
>>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
glob
Tôi thấy toàn cầu dễ dàng hơn để chọn tệp cùng loại hoặc có điểm chung. Nhìn vào ví dụ sau:
import glob
txtfiles = []
for file in glob.glob("*.txt"):
txtfiles.append(file)
glob
với sự hiểu biết danh sách
import glob
mylist = [f for f in glob.glob("*.txt")]
glob
với một chức năng
Hàm trả về một danh sách các phần mở rộng đã cho (.txt, .docx ecc.) Trong đối số
import glob
def filebrowser(ext=""):
"Returns files with an extension"
return [f for f in glob.glob(f"*{ext}")]
x = filebrowser(".txt")
print(x)
>>> ['example.txt', 'fb.txt', 'intro.txt', 'help.txt']
glob
mở rộng mã trước đó
Hàm bây giờ trả về một danh sách các tệp khớp với chuỗi bạn truyền làm đối số
import glob
def filesearch(word=""):
"""Returns a list with all files with the word/extension in it"""
file = []
for f in glob.glob("*"):
if word[0] == ".":
if f.endswith(word):
file.append(f)
return file
elif word in f:
file.append(f)
return file
return file
lookfor = "example", ".py"
for w in lookfor:
print(f"{w:10} found => {filesearch(w)}")
đầu ra
example found => []
.py found => ['search.py']
Lấy tên đường dẫn đầy đủ với
os.path.abspath
Như bạn nhận thấy, bạn không có đường dẫn đầy đủ của tệp trong mã ở trên. Nếu bạn cần phải có đường dẫn tuyệt đối, bạn có thể sử dụng một chức năng khác của os.path
mô-đun được gọi _getfullpathname
, đặt tệp mà bạn nhận được os.listdir()
làm đối số. Có nhiều cách khác để có đường dẫn đầy đủ, vì chúng tôi sẽ kiểm tra sau (tôi đã thay thế, như được đề xuất bởi mexmex, _getfullpathname với abspath
).
import os
files_path = [os.path.abspath(x) for x in os.listdir()]
print(files_path)
>>> ['F:\\documenti\applications.txt', 'F:\\documenti\collections.txt']
Lấy tên đường dẫn đầy đủ của một loại tệp vào tất cả các thư mục con với
walk
Tôi thấy điều này rất hữu ích để tìm nội dung trong nhiều thư mục và nó đã giúp tôi tìm một tệp mà tôi không nhớ tên:
import os
# Getting the current work directory (cwd)
thisdir = os.getcwd()
# r=root, d=directories, f = files
for r, d, f in os.walk(thisdir):
for file in f:
if file.endswith(".docx"):
print(os.path.join(r, file))
os.listdir()
: lấy tệp trong thư mục hiện tại (Python 2)
Trong Python 2, nếu bạn muốn danh sách các tệp trong thư mục hiện tại, bạn phải đưa ra đối số là '.' hoặc os.getcwd () trong phương thức os.listdir.
import os
arr = os.listdir('.')
print(arr)
>>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
Để đi lên trong cây thư mục
# Method 1
x = os.listdir('..')
# Method 2
x= os.listdir('/')
Nhận tệp:
os.listdir()
trong một thư mục cụ thể (Python 2 và 3)
import os
arr = os.listdir('F:\\python')
print(arr)
>>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
Nhận tệp của thư mục con cụ thể với
os.listdir()
import os
x = os.listdir("./content")
os.walk('.')
- thư mục hiện tại
import os
arr = next(os.walk('.'))[2]
print(arr)
>>> ['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']
next(os.walk('.'))
vàos.path.join('dir', 'file')
import os
arr = []
for d,r,f in next(os.walk("F:\\_python")):
for file in f:
arr.append(os.path.join(r,file))
for f in arr:
print(files)
>>> F:\\_python\\dict_class.py
>>> F:\\_python\\programmi.txt
next(os.walk('F:\\')
- có được đường dẫn đầy đủ - hiểu danh sách
[os.path.join(r,file) for r,d,f in next(os.walk("F:\\_python")) for file in f]
>>> ['F:\\_python\\dict_class.py', 'F:\\_python\\programmi.txt']
os.walk
- nhận đường dẫn đầy đủ - tất cả các tệp trong thư mục con **
x = [os.path.join(r,file) for r,d,f in os.walk("F:\\_python") for file in f]
print(x)
>>> ['F:\\_python\\dict.py', 'F:\\_python\\progr.txt', 'F:\\_python\\readl.py']
os.listdir()
- chỉ nhận các tệp txt
arr_txt = [x for x in os.listdir() if x.endswith(".txt")]
print(arr_txt)
>>> ['work.txt', '3ebooks.txt']
Sử dụng
glob
để có được đường dẫn đầy đủ của các tập tin
Nếu tôi cần đường dẫn tuyệt đối của các tập tin:
from path import path
from glob import glob
x = [path(f).abspath() for f in glob("F:\\*.txt")]
for f in x:
print(f)
>>> F:\acquistionline.txt
>>> F:\acquisti_2018.txt
>>> F:\bootstrap_jquery_ecc.txt
Sử dụng
os.path.isfile
để tránh các thư mục trong danh sách
import os.path
listOfFiles = [f for f in os.listdir() if os.path.isfile(f)]
print(listOfFiles)
>>> ['a simple game.py', 'data.txt', 'decorator.py']
Sử dụng
pathlib
từ Python 3.4
import pathlib
flist = []
for p in pathlib.Path('.').iterdir():
if p.is_file():
print(p)
flist.append(p)
>>> error.PNG
>>> exemaker.bat
>>> guiprova.mp3
>>> setup.py
>>> speak_gui2.py
>>> thumb.PNG
Với list comprehension
:
flist = [p for p in pathlib.Path('.').iterdir() if p.is_file()]
Cách khác, sử dụng pathlib.Path()
thay vìpathlib.Path(".")
Sử dụng phương thức toàn cầu trong pathlib.Path ()
import pathlib
py = pathlib.Path().glob("*.py")
for file in py:
print(file)
>>> stack_overflow_list.py
>>> stack_overflow_list_tkinter.py
Nhận tất cả và chỉ các tệp với os.walk
import os
x = [i[2] for i in os.walk('.')]
y=[]
for t in x:
for f in t:
y.append(f)
print(y)
>>> ['append_to_list.py', 'data.txt', 'data1.txt', 'data2.txt', 'data_180617', 'os_walk.py', 'READ2.py', 'read_data.py', 'somma_defaltdic.py', 'substitute_words.py', 'sum_data.py', 'data.txt', 'data1.txt', 'data_180617']
Chỉ nhận các tệp với tiếp theo và đi bộ trong một thư mục
import os
x = next(os.walk('F://python'))[2]
print(x)
>>> ['calculator.bat','calculator.py']
Chỉ nhận các thư mục tiếp theo và đi bộ trong một thư mục
import os
next(os.walk('F://python'))[1] # for the current dir use ('.')
>>> ['python3','others']
Nhận tất cả các tên phụ với
walk
for r,d,f in os.walk("F:\\_python"):
for dirs in d:
print(dirs)
>>> .vscode
>>> pyexcel
>>> pyschool.py
>>> subtitles
>>> _metaprogramming
>>> .ipynb_checkpoints
os.scandir()
từ Python 3.5 trở lên
import os
x = [f.name for f in os.scandir() if f.is_file()]
print(x)
>>> ['calculator.bat','calculator.py']
# Another example with scandir (a little variation from docs.python.org)
# This one is more efficient than os.listdir.
# In this case, it shows the files only in the current directory
# where the script is executed.
import os
with os.scandir() as i:
for entry in i:
if entry.is_file():
print(entry.name)
>>> ebookmaker.py
>>> error.PNG
>>> exemaker.bat
>>> guiprova.mp3
>>> setup.py
>>> speakgui4.py
>>> speak_gui2.py
>>> speak_gui3.py
>>> thumb.PNG
Ví dụ:
Ví dụ. 1: Có bao nhiêu tệp trong thư mục con?
Trong ví dụ này, chúng tôi tìm kiếm số lượng tệp được bao gồm trong tất cả các thư mục và thư mục con của nó.
import os
def count(dir, counter=0):
"returns number of files in dir and subdirs"
for pack in os.walk(dir):
for f in pack[2]:
counter += 1
return dir + " : " + str(counter) + "files"
print(count("F:\\python"))
>>> 'F:\\\python' : 12057 files'
Ex.2: Làm thế nào để sao chép tất cả các tệp từ một thư mục sang một thư mục khác?
Một tập lệnh để đặt hàng trong máy tính của bạn tìm tất cả các tệp thuộc loại (mặc định: pptx) và sao chép chúng trong một thư mục mới.
import os
import shutil
from path import path
destination = "F:\\file_copied"
# os.makedirs(destination)
def copyfile(dir, filetype='pptx', counter=0):
"Searches for pptx (or other - pptx is the default) files and copies them"
for pack in os.walk(dir):
for f in pack[2]:
if f.endswith(filetype):
fullpath = pack[0] + "\\" + f
print(fullpath)
shutil.copy(fullpath, destination)
counter += 1
if counter > 0:
print('-' * 30)
print("\t==> Found in: `" + dir + "` : " + str(counter) + " files\n")
for dir in os.listdir():
"searches for folders that starts with `_`"
if dir[0] == '_':
# copyfile(dir, filetype='pdf')
copyfile(dir, filetype='txt')
>>> _compiti18\Compito Contabilità 1\conti.txt
>>> _compiti18\Compito Contabilità 1\modula4.txt
>>> _compiti18\Compito Contabilità 1\moduloa4.txt
>>> ------------------------
>>> ==> Found in: `_compiti18` : 3 files
Ví dụ. 3: Cách nhận tất cả các tệp trong tệp txt
Trong trường hợp bạn muốn tạo một tệp txt với tất cả các tên tệp:
import os
mylist = ""
with open("filelist.txt", "w", encoding="utf-8") as file:
for eachfile in os.listdir():
mylist += eachfile + "\n"
file.write(mylist)
Ví dụ: txt với tất cả các tệp của ổ cứng
"""
We are going to save a txt file with all the files in your directory.
We will use the function walk()
"""
import os
# see all the methods of os
# print(*dir(os), sep=", ")
listafile = []
percorso = []
with open("lista_file.txt", "w", encoding='utf-8') as testo:
for root, dirs, files in os.walk("D:\\"):
for file in files:
listafile.append(file)
percorso.append(root + "\\" + file)
testo.write(file + "\n")
listafile.sort()
print("N. of files", len(listafile))
with open("lista_file_ordinata.txt", "w", encoding="utf-8") as testo_ordinato:
for file in listafile:
testo_ordinato.write(file + "\n")
with open("percorso.txt", "w", encoding="utf-8") as file_percorso:
for file in percorso:
file_percorso.write(file + "\n")
os.system("lista_file.txt")
os.system("lista_file_ordinata.txt")
os.system("percorso.txt")
Tất cả tệp của C: \ trong một tệp văn bản
Đây là một phiên bản ngắn hơn của mã trước đó. Thay đổi thư mục nơi bắt đầu tìm tệp nếu bạn cần bắt đầu từ vị trí khác. Mã này tạo ra 50 mb trên tệp văn bản trên máy tính của tôi với khoảng 500.000 dòng với các tệp có đường dẫn đầy đủ.
import os
with open("file.txt", "w", encoding="utf-8") as filewrite:
for r, d, f in os.walk("C:\\"):
for file in f:
filewrite.write(f"{r + file}\n")
Cách viết một tệp với tất cả các đường dẫn trong một thư mục thuộc loại
Với chức năng này, bạn có thể tạo một tệp txt sẽ có tên của một loại tệp mà bạn tìm kiếm (ví dụ: pngfile.txt) với tất cả đường dẫn đầy đủ của tất cả các tệp thuộc loại đó. Nó có thể hữu ích đôi khi, tôi nghĩ.
import os
def searchfiles(extension='.ttf', folder='H:\\'):
"Create a txt file with all the file of a type"
with open(extension[1:] + "file.txt", "w", encoding="utf-8") as filewrite:
for r, d, f in os.walk(folder):
for file in f:
if file.endswith(extension):
filewrite.write(f"{r + file}\n")
# looking for png file (fonts) in the hard disk H:\
searchfiles('.png', 'H:\\')
>>> H:\4bs_18\Dolphins5.png
>>> H:\4bs_18\Dolphins6.png
>>> H:\4bs_18\Dolphins7.png
>>> H:\5_18\marketing html\assets\imageslogo2.png
>>> H:\7z001.png
>>> H:\7z002.png
(Mới) Tìm tất cả các tệp và mở chúng bằng GUI tkinter
Tôi chỉ muốn thêm vào năm 2019 một ứng dụng nhỏ này để tìm kiếm tất cả các tệp trong một thư mục và có thể mở chúng bằng cách nhân đôi tên của tệp trong danh sách.
import tkinter as tk
import os
def searchfiles(extension='.txt', folder='H:\\'):
"insert all files in the listbox"
for r, d, f in os.walk(folder):
for file in f:
if file.endswith(extension):
lb.insert(0, r + "\\" + file)
def open_file():
os.startfile(lb.get(lb.curselection()[0]))
root = tk.Tk()
root.geometry("400x400")
bt = tk.Button(root, text="Search", command=lambda:searchfiles('.png', 'H:\\'))
bt.pack()
lb = tk.Listbox(root)
lb.pack(fill="both", expand=1)
lb.bind("<Double-Button>", lambda x: open_file())
root.mainloop()
import os
os.listdir("somedirectory")
sẽ trả về một danh sách tất cả các tệp và thư mục trong "somedirectory".
glob.glob
os.listdir()
luôn trả về tên tệp đơn thuần (không phải đường dẫn tương đối). Những gì glob.glob()
trả về được điều khiển bởi định dạng đường dẫn của mẫu đầu vào.
Một giải pháp một dòng để chỉ nhận danh sách các tệp (không có thư mục con):
filenames = next(os.walk(path))[2]
hoặc tên đường dẫn tuyệt đối:
paths = [os.path.join(path, fn) for fn in next(os.walk(path))[2]]
import os
. Có vẻ ít súc tích hơn glob()
với tôi.
glob()
sẽ coi nó như một tập tin. Phương pháp của bạn sẽ coi nó như một thư mục.
Nhận đường dẫn tệp đầy đủ từ một thư mục và tất cả các thư mục con của nó
import os
def get_filepaths(directory):
"""
This function will generate the file names in a directory
tree by walking the tree either top-down or bottom-up. For each
directory in the tree rooted at directory top (including top itself),
it yields a 3-tuple (dirpath, dirnames, filenames).
"""
file_paths = [] # List which will store all of the full filepaths.
# Walk the tree.
for root, directories, files in os.walk(directory):
for filename in files:
# Join the two strings in order to form the full filepath.
filepath = os.path.join(root, filename)
file_paths.append(filepath) # Add it to the list.
return file_paths # Self-explanatory.
# Run the above function and store its results in a variable.
full_file_paths = get_filepaths("/Users/johnny/Desktop/TEST")
print full_file_paths
sẽ in danh sách:
['/Users/johnny/Desktop/TEST/file1.txt', '/Users/johnny/Desktop/TEST/file2.txt', '/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat']
Nếu bạn muốn, bạn có thể mở và đọc nội dung hoặc chỉ tập trung vào các tệp có phần mở rộng ".dat" như trong mã dưới đây:
for f in full_file_paths:
if f.endswith(".dat"):
print f
/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat
Kể từ phiên bản 3.4, có các trình vòng lặp dựng sẵn cho việc này hiệu quả hơn nhiều so với os.listdir()
:
pathlib
: Mới trong phiên bản 3.4.
>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]
Theo PEP 428 , mục tiêu của pathlib
thư viện là cung cấp một hệ thống phân cấp đơn giản các lớp để xử lý các đường dẫn hệ thống tệp và các hoạt động phổ biến mà người dùng thực hiện đối với chúng.
os.scandir()
: Mới trong phiên bản 3.5.
>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]
Lưu ý rằng os.walk()
sử dụng os.scandir()
thay vì os.listdir()
từ phiên bản 3.5 và tốc độ của nó đã tăng gấp 2-20 lần theo PEP 471 .
Tôi cũng khuyên bạn nên đọc bình luận của ShadowRanger bên dưới.
list
. Có thể sử dụng p.name
thay p
thế thay thế đầu tiên nếu thích.
pathlib.Path()
thể hiện vì chúng có nhiều phương thức hữu ích mà tôi không muốn lãng phí. Bạn cũng có thể gọi str(p)
chúng cho tên đường dẫn.
os.scandir
Giải pháp sẽ hiệu quả hơn so os.listdir
với os.path.is_file
kiểm tra hoặc tương tự, ngay cả khi bạn cần list
(vì vậy bạn không được hưởng lợi từ việc lặp lại lười biếng), bởi vì os.scandir
sử dụng API do OS cung cấp cung cấp cho bạn is_file
thông tin miễn phí khi lặp lại , không có mỗi tập tin chuyến đi vòng vào đĩa để stat
chúng ở tất cả (trên Windows, các DirEntry
s giúp bạn hoàn chỉnh stat
thông tin miễn phí, trên hệ thống * NIX nó cần phải stat
để biết vượt qua is_file
, is_dir
, vv, nhưng DirEntry
bộ nhớ đệm trên đầu stat
cho thuận tiện).
entry.name
để chỉ lấy tên tệp hoặc entry.path
để có đường dẫn đầy đủ. Không còn os.path.join () ở khắp mọi nơi.
Khi câu hỏi được hỏi, tôi tưởng tượng rằng Python 2 , là phiên bản LTS , tuy nhiên các mẫu mã sẽ được chạy bởi Python 3 ( .5 ) (Tôi sẽ giữ chúng theo tiêu chuẩn Python 2 nhất có thể; Python mà tôi sẽ đăng, là từ phiên bản 3.5.4 - trừ khi có quy định khác). Điều đó có hậu quả liên quan đến một từ khóa khác trong câu hỏi: " thêm chúng vào danh sách ":
>>> import sys >>> sys.version '2.7.10 (default, Mar 8 2016, 15:02:46) [MSC v.1600 64 bit (AMD64)]' >>> m = map(lambda x: x, [1, 2, 3]) # Just a dummy lambda function >>> m, type(m) ([1, 2, 3], <type 'list'>) >>> len(m) 3
>>> import sys >>> sys.version '3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)]' >>> m = map(lambda x: x, [1, 2, 3]) >>> m, type(m) (<map object at 0x000001B4257342B0>, <class 'map'>) >>> len(m) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'map' has no len() >>> lm0 = list(m) # Build a list from the generator >>> lm0, type(lm0) ([1, 2, 3], <class 'list'>) >>> >>> lm1 = list(m) # Build a list from the same generator >>> lm1, type(lm1) # Empty list now - generator already consumed ([], <class 'list'>)
Các ví dụ sẽ dựa trên một thư mục có tên root_dir với cấu trúc sau (ví dụ này là dành cho Win , nhưng tôi cũng đang sử dụng cùng một cây trên Lnx ):
E:\Work\Dev\StackOverflow\q003207219>tree /f "root_dir" Folder PATH listing for volume Work Volume serial number is 00000029 3655:6FED E:\WORK\DEV\STACKOVERFLOW\Q003207219\ROOT_DIR ¦ file0 ¦ file1 ¦ +---dir0 ¦ +---dir00 ¦ ¦ ¦ file000 ¦ ¦ ¦ ¦ ¦ +---dir000 ¦ ¦ file0000 ¦ ¦ ¦ +---dir01 ¦ ¦ file010 ¦ ¦ file011 ¦ ¦ ¦ +---dir02 ¦ +---dir020 ¦ +---dir0200 +---dir1 ¦ file10 ¦ file11 ¦ file12 ¦ +---dir2 ¦ ¦ file20 ¦ ¦ ¦ +---dir20 ¦ file200 ¦ +---dir3
[Python 3]: os. listdir ( path = '.' )
Trả về một danh sách chứa tên của các mục trong thư mục được cung cấp bởi đường dẫn. Danh sách theo thứ tự tùy ý và không bao gồm các mục đặc biệt
'.'
và'..'
...
>>> import os >>> root_dir = "root_dir" # Path relative to current dir (os.getcwd()) >>> >>> os.listdir(root_dir) # List all the items in root_dir ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [item for item in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, item))] # Filter items and only keep files (strip out directories) ['file0', 'file1']
Một ví dụ phức tạp hơn ( code_os_listdir.py ):
import os
from pprint import pformat
def _get_dir_content(path, include_folders, recursive):
entries = os.listdir(path)
for entry in entries:
entry_with_path = os.path.join(path, entry)
if os.path.isdir(entry_with_path):
if include_folders:
yield entry_with_path
if recursive:
for sub_entry in _get_dir_content(entry_with_path, include_folders, recursive):
yield sub_entry
else:
yield entry_with_path
def get_dir_content(path, include_folders=True, recursive=True, prepend_folder_name=True):
path_len = len(path) + len(os.path.sep)
for item in _get_dir_content(path, include_folders, recursive):
yield item if prepend_folder_name else item[path_len:]
def _get_dir_content_old(path, include_folders, recursive):
entries = os.listdir(path)
ret = list()
for entry in entries:
entry_with_path = os.path.join(path, entry)
if os.path.isdir(entry_with_path):
if include_folders:
ret.append(entry_with_path)
if recursive:
ret.extend(_get_dir_content_old(entry_with_path, include_folders, recursive))
else:
ret.append(entry_with_path)
return ret
def get_dir_content_old(path, include_folders=True, recursive=True, prepend_folder_name=True):
path_len = len(path) + len(os.path.sep)
return [item if prepend_folder_name else item[path_len:] for item in _get_dir_content_old(path, include_folders, recursive)]
def main():
root_dir = "root_dir"
ret0 = get_dir_content(root_dir, include_folders=True, recursive=True, prepend_folder_name=True)
lret0 = list(ret0)
print(ret0, len(lret0), pformat(lret0))
ret1 = get_dir_content_old(root_dir, include_folders=False, recursive=True, prepend_folder_name=False)
print(len(ret1), pformat(ret1))
if __name__ == "__main__":
main()
Ghi chú :
Đầu ra :
(py35x64_test) E:\Work\Dev\StackOverflow\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" "code_os_listdir.py" <generator object get_dir_content at 0x000001BDDBB3DF10> 22 ['root_dir\\dir0', 'root_dir\\dir0\\dir00', 'root_dir\\dir0\\dir00\\dir000', 'root_dir\\dir0\\dir00\\dir000\\file0000', 'root_dir\\dir0\\dir00\\file000', 'root_dir\\dir0\\dir01', 'root_dir\\dir0\\dir01\\file010', 'root_dir\\dir0\\dir01\\file011', 'root_dir\\dir0\\dir02', 'root_dir\\dir0\\dir02\\dir020', 'root_dir\\dir0\\dir02\\dir020\\dir0200', 'root_dir\\dir1', 'root_dir\\dir1\\file10', 'root_dir\\dir1\\file11', 'root_dir\\dir1\\file12', 'root_dir\\dir2', 'root_dir\\dir2\\dir20', 'root_dir\\dir2\\dir20\\file200', 'root_dir\\dir2\\file20', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1'] 11 ['dir0\\dir00\\dir000\\file0000', 'dir0\\dir00\\file000', 'dir0\\dir01\\file010', 'dir0\\dir01\\file011', 'dir1\\file10', 'dir1\\file11', 'dir1\\file12', 'dir2\\dir20\\file200', 'dir2\\file20', 'file0', 'file1']
[Python 3]: os. scandir ( path = '.' ) ( Python 3.5 +, backport: [PyPI]: scandir )
Trả về một iterator của các đối tượng os.DirEntry tương ứng với các mục trong thư mục được cung cấp bởi đường dẫn . Các mục được mang lại theo thứ tự tùy ý, và các mục đặc biệt
'.'
và'..'
không được bao gồm.Sử dụng scandir () thay cho listdir () có thể làm tăng đáng kể hiệu năng của mã cũng cần thông tin thuộc tính loại tệp hoặc thuộc tính tệp, vì các đối tượng os.DirEntry lộ thông tin này nếu hệ điều hành cung cấp nó khi quét thư mục. Tất cả các phương thức os.DirEntry có thể thực hiện một cuộc gọi hệ thống, nhưng is_dir () và is_file () thường chỉ yêu cầu một cuộc gọi hệ thống cho các liên kết tượng trưng; os.DirEntry.stat () luôn yêu cầu một cuộc gọi hệ thống trên Unix nhưng chỉ yêu cầu một liên kết tượng trưng trên Windows.
>>> import os >>> root_dir = os.path.join(".", "root_dir") # Explicitly prepending current directory >>> root_dir '.\\root_dir' >>> >>> scandir_iterator = os.scandir(root_dir) >>> scandir_iterator <nt.ScandirIterator object at 0x00000268CF4BC140> >>> [item.path for item in scandir_iterator] ['.\\root_dir\\dir0', '.\\root_dir\\dir1', '.\\root_dir\\dir2', '.\\root_dir\\dir3', '.\\root_dir\\file0', '.\\root_dir\\file1'] >>> >>> [item.path for item in scandir_iterator] # Will yield an empty list as it was consumed by previous iteration (automatically performed by the list comprehension) [] >>> >>> scandir_iterator = os.scandir(root_dir) # Reinitialize the generator >>> for item in scandir_iterator : ... if os.path.isfile(item.path): ... print(item.name) ... file0 file1
Ghi chú :
os.listdir
[Python 3]: os. đi bộ ( top, topdown = True, onerror = Không, followlinks = Sai )
Tạo tên tệp trong cây thư mục bằng cách đi bộ cây từ trên xuống hoặc từ dưới lên. Đối với mỗi thư mục trong cây bén rễ tại thư mục trên (bao gồm cả đầu chính nó), nó mang lại một 3-tuple (
dirpath
,dirnames
,filenames
).
>>> import os >>> root_dir = os.path.join(os.getcwd(), "root_dir") # Specify the full path >>> root_dir 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir' >>> >>> walk_generator = os.walk(root_dir) >>> root_dir_entry = next(walk_generator) # First entry corresponds to the root dir (passed as an argument) >>> root_dir_entry ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir', ['dir0', 'dir1', 'dir2', 'dir3'], ['file0', 'file1']) >>> >>> root_dir_entry[1] + root_dir_entry[2] # Display dirs and files (direct descendants) in a single list ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [os.path.join(root_dir_entry[0], item) for item in root_dir_entry[1] + root_dir_entry[2]] # Display all the entries in the previous list by their full path ['E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file0', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file1'] >>> >>> for entry in walk_generator: # Display the rest of the elements (corresponding to every subdir) ... print(entry) ... ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0', ['dir00', 'dir01', 'dir02'], []) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00', ['dir000'], ['file000']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00\\dir000', [], ['file0000']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir01', [], ['file010', 'file011']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02', ['dir020'], []) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020', ['dir0200'], []) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020\\dir0200', [], []) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1', [], ['file10', 'file11', 'file12']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2', ['dir20'], ['file20']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2\\dir20', [], ['file200']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3', [], [])
Ghi chú :
os.scandir
( os.listdir
trên các phiên bản cũ hơn)[Python 3]: toàn cầu. global ( tên đường dẫn, *, đệ quy = Sai ) ( [Python 3]: global . iglob ( tên đường dẫn, *, đệ quy = Sai ) )
Trả về một danh sách các tên đường dẫn có thể trống khớp với tên đường dẫn , phải là một chuỗi chứa một đặc tả đường dẫn. tên đường dẫn có thể là tuyệt đối (như
/usr/src/Python-1.5/Makefile
) hoặc tương đối (như../../Tools/*/*.gif
) và có thể chứa các ký tự đại diện kiểu vỏ. Symlink bị hỏng được bao gồm trong các kết quả (như trong vỏ).
...
Đã thay đổi trong phiên bản 3.5 : Hỗ trợ các thuật toán đệ quy bằng cách sử dụng**
.
>>> import glob, os >>> wildcard_pattern = "*" >>> root_dir = os.path.join("root_dir", wildcard_pattern) # Match every file/dir name >>> root_dir 'root_dir\\*' >>> >>> glob_list = glob.glob(root_dir) >>> glob_list ['root_dir\\dir0', 'root_dir\\dir1', 'root_dir\\dir2', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1'] >>> >>> [item.replace("root_dir" + os.path.sep, "") for item in glob_list] # Strip the dir name and the path separator from begining ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> for entry in glob.iglob(root_dir + "*", recursive=True): ... print(entry) ... root_dir\ root_dir\dir0 root_dir\dir0\dir00 root_dir\dir0\dir00\dir000 root_dir\dir0\dir00\dir000\file0000 root_dir\dir0\dir00\file000 root_dir\dir0\dir01 root_dir\dir0\dir01\file010 root_dir\dir0\dir01\file011 root_dir\dir0\dir02 root_dir\dir0\dir02\dir020 root_dir\dir0\dir02\dir020\dir0200 root_dir\dir1 root_dir\dir1\file10 root_dir\dir1\file11 root_dir\dir1\file12 root_dir\dir2 root_dir\dir2\dir20 root_dir\dir2\dir20\file200 root_dir\dir2\file20 root_dir\dir3 root_dir\file0 root_dir\file1
Ghi chú :
os.listdir
[Python 3]: lớp dẫn đường. Đường dẫn ( * đường dẫn ) ( Python 3,4 +, backport: [PyPI]: pathlib2 )
>>> import pathlib >>> root_dir = "root_dir" >>> root_dir_instance = pathlib.Path(root_dir) >>> root_dir_instance WindowsPath('root_dir') >>> root_dir_instance.name 'root_dir' >>> root_dir_instance.is_dir() True >>> >>> [item.name for item in root_dir_instance.glob("*")] # Wildcard searching for all direct descendants ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [os.path.join(item.parent.name, item.name) for item in root_dir_instance.glob("*") if not item.is_dir()] # Display paths (including parent) for files only ['root_dir\\file0', 'root_dir\\file1']
Ghi chú :
[Python 2]: dircache.listdir (đường dẫn) (chỉ Python 2 )
os.listdir
với bộ nhớ đệmdef listdir(path):
"""List directory contents, using cache."""
try:
cached_mtime, list = cache[path]
del cache[path]
except KeyError:
cached_mtime, list = -1, []
mtime = os.stat(path).st_mtime
if mtime != cached_mtime:
list = os.listdir(path)
list.sort()
cache[path] = mtime, list
return list
[man7]: OPENDIR (3) / [man7]: READDIR (3) / [man7]: ĐÃ ĐÓNG CỬA (3) qua [Python 3]: ctypes - Thư viện hàm nước ngoài cho Python ( cụ thể là POSIX )
ctypes là một thư viện hàm nước ngoài cho Python. Nó cung cấp các kiểu dữ liệu tương thích C và cho phép gọi các hàm trong DLL hoặc thư viện dùng chung. Nó có thể được sử dụng để bọc các thư viện này trong Python thuần túy.
code_ctypes.py :
#!/usr/bin/env python3
import sys
from ctypes import Structure, \
c_ulonglong, c_longlong, c_ushort, c_ubyte, c_char, c_int, \
CDLL, POINTER, \
create_string_buffer, get_errno, set_errno, cast
DT_DIR = 4
DT_REG = 8
char256 = c_char * 256
class LinuxDirent64(Structure):
_fields_ = [
("d_ino", c_ulonglong),
("d_off", c_longlong),
("d_reclen", c_ushort),
("d_type", c_ubyte),
("d_name", char256),
]
LinuxDirent64Ptr = POINTER(LinuxDirent64)
libc_dll = this_process = CDLL(None, use_errno=True)
# ALWAYS set argtypes and restype for functions, otherwise it's UB!!!
opendir = libc_dll.opendir
readdir = libc_dll.readdir
closedir = libc_dll.closedir
def get_dir_content(path):
ret = [path, list(), list()]
dir_stream = opendir(create_string_buffer(path.encode()))
if (dir_stream == 0):
print("opendir returned NULL (errno: {:d})".format(get_errno()))
return ret
set_errno(0)
dirent_addr = readdir(dir_stream)
while dirent_addr:
dirent_ptr = cast(dirent_addr, LinuxDirent64Ptr)
dirent = dirent_ptr.contents
name = dirent.d_name.decode()
if dirent.d_type & DT_DIR:
if name not in (".", ".."):
ret[1].append(name)
elif dirent.d_type & DT_REG:
ret[2].append(name)
dirent_addr = readdir(dir_stream)
if get_errno():
print("readdir returned NULL (errno: {:d})".format(get_errno()))
closedir(dir_stream)
return ret
def main():
print("{:s} on {:s}\n".format(sys.version, sys.platform))
root_dir = "root_dir"
entries = get_dir_content(root_dir)
print(entries)
if __name__ == "__main__":
main()
Ghi chú :
os.walk
định dạng của. Tôi không bận tâm làm cho nó đệ quy, nhưng bắt đầu từ mã hiện có, đó sẽ là một nhiệm vụ khá nhỏĐầu ra :
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q003207219]> ./code_ctypes.py 3.5.2 (default, Nov 12 2018, 13:43:14) [GCC 5.4.0 20160609] on linux ['root_dir', ['dir2', 'dir1', 'dir3', 'dir0'], ['file1', 'file0']]
[ActiveState.Docs]: win32file.FindFilesW ( Thắng cụ thể)
Lấy danh sách tên tệp phù hợp, sử dụng API Unicode của Windows. Giao diện cho API FindFirstFileW / FindNextFileW / Tìm các hàm đóng.
>>> import os, win32file, win32con >>> root_dir = "root_dir" >>> wildcard = "*" >>> root_dir_wildcard = os.path.join(root_dir, wildcard) >>> entry_list = win32file.FindFilesW(root_dir_wildcard) >>> len(entry_list) # Don't display the whole content as it's too long 8 >>> [entry[-2] for entry in entry_list] # Only display the entry names ['.', '..', 'dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [entry[-2] for entry in entry_list if entry[0] & win32con.FILE_ATTRIBUTE_DIRECTORY and entry[-2] not in (".", "..")] # Filter entries and only display dir names (except self and parent) ['dir0', 'dir1', 'dir2', 'dir3'] >>> >>> [os.path.join(root_dir, entry[-2]) for entry in entry_list if entry[0] & (win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_ATTRIBUTE_ARCHIVE)] # Only display file "full" names ['root_dir\\file0', 'root_dir\\file1']
Ghi chú :
win32file.FindFilesW
là một phần của [GitHub]: mhammond / PyWin32 - Python cho Windows (PyWin32) Extensions , mà là một Python wrapper trên WINAPI sGhi chú :
Mã có nghĩa là di động (ngoại trừ những nơi nhắm mục tiêu đến một khu vực cụ thể - được đánh dấu) hoặc chéo:
Nhiều kiểu đường dẫn (tuyệt đối, họ hàng) đã được sử dụng trên các biến thể trên, để minh họa thực tế là "công cụ" được sử dụng linh hoạt theo hướng này
os.listdir
và os.scandir
sử dụng opendir / readdir / closir ( [MS.Docs]: Hàm FindFirstFileW / [MS.Docs]: Hàm FindNextFileW / [MS.Docs]: Hàm FindClose ) (thông qua [GitHub]: python / cpython - (master) Mô-đun / posixmodule.c )
win32file.FindFilesW
cũng sử dụng các hàm ( Win cụ thể) đó (thông qua [GitHub]: mhammond / pywin32 - (master) pywin32 / win32 / src / win32file.i )
_get_dir_content (từ điểm # 1. ) có thể được triển khai bằng bất kỳ cách tiếp cận nào trong số này (một số sẽ yêu cầu nhiều công việc hơn và một số ít hơn)
filter_func=lambda x: True
(điều này không loại bỏ bất cứ điều gì) và bên trong _get_dir_content một cái gì đó như: if not filter_func(entry_with_path): continue
(nếu chức năng không thành công cho một mục nhập, nó sẽ bị bỏ qua), nhưng mã càng phức tạp thì càng mất nhiều thời gian để thực thiĐáng chú ý! Vì đệ quy được sử dụng, tôi phải đề cập rằng tôi đã thực hiện một số thử nghiệm trên máy tính xách tay của mình ( Win 10 x64 ), hoàn toàn không liên quan đến vấn đề này và khi mức đệ quy đạt đến các giá trị ở đâu đó trong phạm vi ( 990 .. 1000) ( đệ quy - 1000 (mặc định)), tôi đã có StackOverflow :). Nếu cây thư mục vượt quá giới hạn đó (tôi không phải là chuyên gia về FS , vì vậy tôi không biết liệu điều đó có khả thi hay không), đó có thể là một vấn đề.
Tôi cũng phải đề cập rằng tôi đã không cố gắng tăng đệ quy vì tôi không có kinh nghiệm trong khu vực (tôi có thể tăng bao nhiêu trước khi phải tăng stack ở HĐHmức), nhưng trên lý thuyết sẽ luôn có khả năng thất bại, nếu độ sâu dir lớn hơn mức đệ quy cao nhất có thể (trên máy đó)
Các mẫu mã chỉ dành cho mục đích trình diễn. Điều đó có nghĩa là tôi đã không tính đến việc xử lý lỗi (tôi không nghĩ có bất kỳ lần thử / ngoại trừ / khác / cuối cùng ), vì vậy mã không mạnh mẽ (lý do là: giữ cho nó đơn giản và ngắn nhất có thể ). Đối với sản xuất , xử lý lỗi cũng nên được thêm vào
Chỉ sử dụng Python làm trình bao bọc
Hương vị nổi tiếng nhất mà tôi biết là cách tôi gọi là phương pháp quản trị hệ thống :
grep
/ findstr
) hoặc định dạng đầu ra có thể được thực hiện ở cả hai bên, nhưng tôi sẽ không nhấn mạnh vào nó. Ngoài ra, tôi cố tình sử dụng os.system
thay vì subprocess.Popen
.(py35x64_test) E:\Work\Dev\StackOverflow\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os;os.system(\"dir /b root_dir\")" dir0 dir1 dir2 dir3 file0 file1
Nói chung, cách tiếp cận này là cần tránh, vì nếu một số định dạng đầu ra lệnh hơi khác nhau giữa các phiên bản / hương vị của hệ điều hành , thì mã phân tích cũng phải được điều chỉnh; không đề cập đến sự khác biệt giữa các địa phương).
Tôi thực sự thích câu trả lời của adamk , đề nghị bạn sử dụng glob()
, từ mô-đun cùng tên. Điều này cho phép bạn có mô hình khớp với *
s.
Nhưng như những người khác đã chỉ ra trong các bình luận, glob()
có thể bị vấp phải các hướng chém không nhất quán. Để giúp với điều đó, tôi khuyên bạn nên sử dụng join()
và các expanduser()
chức năng trong os.path
mô-đun, và có lẽ cả getcwd()
chức năng trong os
mô-đun.
Ví dụ:
from glob import glob
# Return everything under C:\Users\admin that contains a folder called wlp.
glob('C:\Users\admin\*\wlp')
Ở trên là khủng khiếp - đường dẫn đã được mã hóa cứng và sẽ chỉ hoạt động trên Windows giữa tên ổ đĩa và \
s được mã hóa cứng vào đường dẫn.
from glob import glob
from os.path import join
# Return everything under Users, admin, that contains a folder called wlp.
glob(join('Users', 'admin', '*', 'wlp'))
Ở trên hoạt động tốt hơn, nhưng nó phụ thuộc vào tên thư mục Users
thường thấy trên Windows và không thường thấy trên các HĐH khác. Nó cũng dựa vào người dùng có một tên cụ thể admin
,.
from glob import glob
from os.path import expanduser, join
# Return everything under the user directory that contains a folder called wlp.
glob(join(expanduser('~'), '*', 'wlp'))
Điều này hoạt động hoàn hảo trên tất cả các nền tảng.
Một ví dụ tuyệt vời khác hoạt động hoàn hảo trên các nền tảng và làm một cái gì đó hơi khác một chút:
from glob import glob
from os import getcwd
from os.path import join
# Return everything under the current directory that contains a folder called wlp.
glob(join(getcwd(), '*', 'wlp'))
Hy vọng những ví dụ này giúp bạn thấy sức mạnh của một vài chức năng bạn có thể tìm thấy trong các mô-đun thư viện Python tiêu chuẩn.
**
hoạt động miễn là bạn đặt recursive = True
. Xem các tài liệu ở đây: docs.python.org/3.5/library/glob.html#glob.glob
Nếu bạn đang tìm kiếm một triển khai tìm kiếm Python , đây là một công thức tôi sử dụng khá thường xuyên:
from findtools.find_files import (find_files, Match)
# Recursively find all *.sh files in **/usr/bin**
sh_files_pattern = Match(filetype='f', name='*.sh')
found_files = find_files(path='/usr/bin', match=sh_files_pattern)
for found_file in found_files:
print found_file
Vì vậy, tôi đã tạo ra một gói PyPI từ đó và cũng có một kho GitHub . Tôi hy vọng rằng ai đó tìm thấy nó có khả năng hữu ích cho mã này.
Để có kết quả lớn hơn, bạn có thể sử dụng listdir()
phương thức của os
mô-đun cùng với trình tạo (trình tạo là trình lặp mạnh mẽ giữ trạng thái của nó, nhớ không?). Đoạn mã sau hoạt động tốt với cả hai phiên bản: Python 2 và Python 3.
Đây là một mã:
import os
def files(path):
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
yield file
for file in files("."):
print (file)
Các listdir()
phương thức trả về danh sách các mục cho các thư mục nhất định. Phương thức os.path.isfile()
trả về True
nếu mục đã cho là một tệp. Và yield
toán tử thoát khỏi func nhưng vẫn giữ trạng thái hiện tại và nó chỉ trả về tên của mục được phát hiện dưới dạng tệp. Tất cả những điều trên cho phép chúng ta lặp qua chức năng của trình tạo.
Trả về một danh sách các filepath tuyệt đối, không tái diễn thành các thư mục con
L = [os.path.join(os.getcwd(),f) for f in os.listdir('.') if os.path.isfile(os.path.join(os.getcwd(),f))]
os.path.abspath(f)
sẽ là một thay thế rẻ hơn cho os.path.join(os.getcwd(),f)
.
cwd = os.path.abspath('.')
, sau đó sử dụng cwd
thay vì '.'
và os.getcwd()
trong suốt để tránh vô số cuộc gọi hệ thống dư thừa.
import os
import os.path
def get_files(target_dir):
item_list = os.listdir(target_dir)
file_list = list()
for item in item_list:
item_dir = os.path.join(target_dir,item)
if os.path.isdir(item_dir):
file_list += get_files(item_dir)
else:
file_list.append(item_dir)
return file_list
Ở đây tôi sử dụng một cấu trúc đệ quy.
Một giáo viên thông thái đã nói với tôi một lần rằng:
Khi có một số cách được thiết lập để làm một cái gì đó, không có cách nào là tốt cho tất cả các trường hợp.
Do đó tôi sẽ thêm một giải pháp cho một tập hợp con của vấn đề: khá thường xuyên, chúng tôi chỉ muốn kiểm tra xem một tệp có khớp với chuỗi bắt đầu và chuỗi kết thúc hay không mà không đi vào thư mục con. Do đó, chúng tôi muốn một hàm trả về danh sách tên tệp, như:
filenames = dir_filter('foo/baz', radical='radical', extension='.txt')
Nếu bạn quan tâm đến việc khai báo hai hàm đầu tiên, điều này có thể được thực hiện:
def file_filter(filename, radical='', extension=''):
"Check if a filename matches a radical and extension"
if not filename:
return False
filename = filename.strip()
return(filename.startswith(radical) and filename.endswith(extension))
def dir_filter(dirname='', radical='', extension=''):
"Filter filenames in directory according to radical and extension"
if not dirname:
dirname = '.'
return [filename for filename in os.listdir(dirname)
if file_filter(filename, radical, extension)]
Giải pháp này có thể dễ dàng khái quát hóa bằng các biểu thức thông thường (và bạn có thể muốn thêm một pattern
đối số, nếu bạn không muốn các mẫu của mình luôn bám vào phần đầu hoặc phần cuối của tên tệp).
Một biến thể rất dễ đọc khác cho Python 3.4+ là sử dụng pathlib.Path.glob:
from pathlib import Path
folder = '/foo'
[f for f in Path(folder).glob('*') if f.is_file()]
Thật đơn giản để làm cho cụ thể hơn, ví dụ: chỉ tìm các tệp nguồn Python không phải là liên kết tượng trưng, trong tất cả các thư mục con:
[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]
Đây là chức năng mục đích chung của tôi cho việc này. Nó trả về một danh sách các đường dẫn tệp chứ không phải tên tệp vì tôi thấy rằng nó hữu ích hơn. Nó có một vài đối số tùy chọn làm cho nó linh hoạt. Chẳng hạn, tôi thường sử dụng nó với các đối số như pattern='*.txt'
hoặc subfolders=True
.
import os
import fnmatch
def list_paths(folder='.', pattern='*', case_sensitive=False, subfolders=False):
"""Return a list of the file paths matching the pattern in the specified
folder, optionally including files inside subfolders.
"""
match = fnmatch.fnmatchcase if case_sensitive else fnmatch.fnmatch
walked = os.walk(folder) if subfolders else [next(os.walk(folder))]
return [os.path.join(root, f)
for root, dirnames, filenames in walked
for f in filenames if match(f, pattern)]
Tôi sẽ cung cấp một lớp lót mẫu trong đó có thể cung cấp loại đường dẫn và loại tệp làm đầu vào. Mã này trả về một danh sách tên tệp có phần mở rộng csv. Sử dụng . trong trường hợp tất cả các tập tin cần phải được trả lại. Điều này cũng sẽ quét đệ quy các thư mục con.
[y for x in os.walk(sourcePath) for y in glob(os.path.join(x[0], '*.csv'))]
Sửa đổi phần mở rộng tập tin và đường dẫn nguồn khi cần thiết.
glob
, sau đó chỉ cần sử dụng glob('**/*.csv', recursive=True)
. Không cần kết hợp điều này với os.walk()
để lặp lại ( recursive
và **
được hỗ trợ kể từ Python 3.5).
Đối với python2: pip cài đặt rglob
import rglob
file_list=rglob.rglob("/home/base/dir/", "*")
print file_list
dircache là "Không dùng nữa kể từ phiên bản 2.6: Mô-đun dircache đã bị xóa trong Python 3.0."
import dircache
list = dircache.listdir(pathname)
i = 0
check = len(list[0])
temp = []
count = len(list)
while count != 0:
if len(list[i]) != check:
temp.append(list[i-1])
check = len(list[i])
else:
i = i + 1
count = count - 1
print temp