Làm cách nào để liệt kê tất cả các tệp của một thư mục?

3468
duhhunjonn 2010-07-09 09:31.

Làm cách nào để liệt kê tất cả các tệp của một thư mục bằng Python và thêm chúng vào a list?

21 answers

4634
pycruft 2010-07-09 11:01.

os.listdir()sẽ cung cấp cho bạn mọi thứ có trong thư mục - tệpthư mục .

Nếu bạn chỉ muốn các tệp, bạn có thể lọc nó 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 filedirs cho bạn. Nếu bạn chỉ muốn thư mục trên cùng, bạn 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
1822
adamk 2010-07-10 08:13.

Tôi thích sử dụng globmô-đun hơn, vì nó phù hợp và mở rộng mẫu.

import glob
print(glob.glob("/home/adam/*.txt"))

Nó sẽ trả về một danh sách với các tệp được truy vấn:

['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]
1016
Giovanni G. PY 2017-01-04 05:36.

Nhận danh sách các tệp bằng Python 2 và 3

os.listdir() - danh sách trong thư mục hiện tại

Với listdir trong mô-đun hệ điều hành, bạn nhận được các tệp và các thư mục trong dir hiện tại

 import os
 arr = os.listdir()
 print(arr)
 
 >>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

Python 2

Bạn cần ''

 arr = os.listdir('')

Tìm trong một danh bạ

arr = os.listdir('c:\\files')

glob từ thế giới

với toàn cầu, bạn có thể chỉ định một loại tệp để liệt kê như thế này

import glob

txtfiles = []
for file in glob.glob("*.txt"):
    txtfiles.append(file)

glob tôi là một người hiểu danh sách

mylist = [f for f in glob.glob("*.txt")]

Lấy tên đường dẫn đầy đủ với os.path.abspath

Đổi lại bạn sẽ có được con đường đầy đủ

 import os
 files_path = [os.path.abspath(x) for x in os.listdir()]
 print(files_path)
 
 >>> ['F:\\documenti\applications.txt', 'F:\\documenti\collections.txt']

Đi bộ: đi qua các thư mục con

os.walk trả về thư mục gốc, danh sách thư mục và danh sách tệp, đó là lý do tại sao tôi giải nén chúng trong r, d, f trong vòng lặp for; sau đó, nó tìm kiếm các tệp và thư mục khác trong các thư mục con của thư mục gốc, v.v. cho đến khi không có thư mục con nào.

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 cung cấp đố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 các tệp của một 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('.'))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:\\') - lấy đườ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 - lấy đường dẫn đầy đủ - tất cả các tệp trong dirs phụ **

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để lấy đường dẫn đầy đủ của các tệp

Nếu tôi cần đường dẫn tuyệt đối của các tệp:

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 pathlibtừ 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()]

Ngoài ra, hãy sử dụng pathlib.Path()thay vìpathlib.Path(".")

Sử dụng phương thức global 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 next 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 với 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 con 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 các 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ả thư mục và các 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'

Ví dụ 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 để sắp xếp thứ tự trong máy tính của bạn khi tìm tất cả các tệp cùng loại (mặc định: pptx) và sao chép chúng vào 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 lấy 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à 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 một cái gì đó ít hơn 500.000 dòng với các tệp có đường dẫn hoàn chỉnh.

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 ghi một tệp với tất cả các đường dẫn trong một loại thư mục

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 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 đó. Đôi khi nó có thể hữu ích, 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 tkinter GUI

Tôi chỉ muốn thêm vào năm 2019 này một ứng dụng nhỏ để tìm kiếm tất cả các tệp trong một dir và có thể mở chúng bằng cách nhấp đúp vào 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()
863
sepp2k 2010-07-09 09:35.
import os
os.listdir("somedirectory")

sẽ trả về danh sách tất cả các tệp và thư mục trong "somedirectory".

165
Remi 2014-01-19 07:42.

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]]
136
Johnny 2013-10-11 14:55.

Lấy đườ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")

  • Đường dẫn tôi đã cung cấp trong hàm trên chứa 3 tệp— hai tệp trong thư mục gốc và một tệp khác trong thư mục con có tên "SUBFOLDER." Bây giờ bạn có thể làm những việc như:
  • 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 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ã bên dưới:

for f in full_file_paths:
  if f.endswith(".dat"):
    print f

/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat

81
SzieberthAdam 2015-06-19 10:58.

Kể từ phiên bản 3.4 có các trình vòng lặp nội trang cho điều này hiệu quả hơn rất 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 đích của pathlibthư viện là cung cấp một hệ thống phân cấp đơn giản của các lớp để xử lý các đường dẫn hệ thống tệp và các thao tác phổ biến mà người dùng thực hiện trên 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 lên 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.

57
CristiFati 2018-01-23 17:09.

Ghi chú sơ bộ

  • Mặc dù có sự khác biệt rõ ràng giữa các thuật ngữ tệpthư mục trong văn bản câu hỏi, một số người có thể tranh luận rằng thư mục thực sự là các tệp đặc biệt
  • Câu lệnh: " all files of a directory " có thể được hiểu theo hai cách:
    1. Tất cả trực tiếp (hoặc cấp 1) hậu duệ duy nhất
    2. Tất cả con cháu trong toàn bộ cây thư mục (bao gồm cả những con trong thư mục con)
  • Khi câu hỏi được đặt ra, 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 tuân thủ Python 2 càng tốt; ngoài ra, bất kỳ mã nào thuộc về Python mà tôi sắp đăng, là từ v3.5.4 - trừ khi được chỉ đị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 ":

    • Trong các phiên bản Python 2.2 trước , chuỗi (lặp lại) chủ yếu được biểu diễn bằng danh sách (bộ, bộ, ...)
    • Trong Python 2.2 , khái niệm về trình tạo ( [Python.Wiki]: Trình tạo ) - được gọi là [Python 3]: Câu lệnh lợi nhuận ) - đã được giới thiệu. Khi thời gian trôi qua, các đối tác của trình tạo bắt đầu xuất hiện cho các hàm trả về / hoạt động với danh sách
    • Trong Python 3 , trình tạo là hành vi mặc định
    • Không chắc liệu việc trả về một danh sách có còn là bắt buộc hay không (hoặc trình tạo cũng vậy), nhưng việc chuyển một trình tạo đến phương thức khởi tạo danh sách , sẽ tạo ra một danh sách từ đó (và cũng sử dụng nó). Ví dụ bên dưới minh họa sự khác biệt trên [Python 3]: map ( hàm, có thể lặp, ... )
    >>> 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 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
    


Các giải pháp

Phương pháp tiếp cận có lập trình:

  1. [Python 3]: hệ điều hành. listdir ( đường dẫn = '.' )

    Trả về một danh sách có 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 nhập đặc biệt '.''..'...


    >>> 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ú :

    • Có hai cách triển khai:
      • Một cái sử dụng bộ tạo (tất nhiên ở đây nó có vẻ vô dụng, vì tôi ngay lập tức chuyển đổi kết quả thành một danh sách)
      • Cái cổ điển (tên hàm kết thúc bằng _old )
    • Đệ quy được sử dụng (để vào thư mục con)
    • Đối với mỗi triển khai có hai chức năng:
      • Một cái bắt đầu bằng dấu gạch dưới ( _ ): "private" (không nên được gọi trực tiếp) - thực hiện tất cả công việc
      • Công khai (bao bọc trước đó): nó chỉ loại bỏ đường dẫn ban đầu (nếu được yêu cầu) khỏi các mục được trả về. Đó là một triển khai xấu xí, nhưng đó là ý tưởng duy nhất mà tôi có thể đưa ra vào thời điểm này
    • Về mặt hiệu suất, trình tạo thường nhanh hơn một chút (xem xét cả thời gian tạolặp ), nhưng tôi đã không kiểm tra chúng trong các hàm đệ quy và tôi cũng đang lặp lại bên trong hàm trên các trình tạo bên trong - không biết hiệu suất như thế nào thân thiện là vậy
    • Chơi với các đối số để nhận được các kết quả khác nhau


    Đầ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']
    


  1. [Python 3]: hệ điều hành. scandir ( path = '.' ) ( Python 3.5 +, cổng quay lại: [PyPI]: scandir )

    Trả về một trình lặp của các đối tượng os.DirEntry tương ứng với các mục nhập trong thư mục được cung cấp bởi đường dẫn . Các mục nhập được tạo ra theo thứ tự tùy ý, và các mục nhập đặc biệt '.''..'không được bao gồm.

    Sử dụng scandir () thay vì listdir () có thể làm tăng đáng kể hiệu suất của mã cũng cần loại tệp hoặc thông tin thuộc tính tệp, vì đối tượng os.DirEntry tiết lộ thông tin này nếu hệ điều hành cung cấp thông tin đó 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 lệnh gọi hệ thống, nhưng is_dir () và is_file () thường chỉ yêu cầu một lệnh 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 lệnh gọi hệ thống trên Unix nhưng chỉ yêu cầu một lệnh gọi cho các 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ú :

    • Nó tương tự như os.listdir
    • Nhưng nó cũng linh hoạt hơn (và cung cấp nhiều chức năng hơn), nhiều ic Python hơn (và trong một số trường hợp, nhanh hơn)


  1. [Python 3]: hệ điều hành. walk ( top, topdown = True, onerror = None, followlinks = False )

    Tạo tên tệp trong cây thư mục bằng cách di chuyển 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ú :

    • Dưới cảnh, nó sử dụng os.scandir( os.listdirtrên các phiên bản cũ hơn)
    • Nó thực hiện công việc nặng nhọc bằng cách lặp lại trong các thư mục con


  1. [Python 3]: cầu. cầu ( tên đường dẫn, *, đệ quy = Sai ) ( [Python 3]: cầu. iglob ( tên đường dẫn, *, đệ quy = Sai ) )

    Trả về danh sách tên đường dẫn có thể trống phù hợp với tên đường dẫn , danh sách này phải là một chuỗi chứa đặc tả đường dẫn. tên đường dẫn có thể là tuyệt đối (like /usr/src/Python-1.5/Makefile) hoặc tương đối (like ../../Tools/*/*.gif) và có thể chứa các ký tự đại diện kiểu shell. Các liên kết tượng trưng bị hỏng được đưa vào kết quả (như trong shell).
    ...
    Đã thay đổi trong phiên bản 3.5 : Hỗ trợ cho các quả cầu đệ quy 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ú :

    • Sử dụng os.listdir
    • Đối với những cây lớn (đặc biệt nếu bật đệ quy ), iglob được ưu tiên
    • Cho phép lọc nâng cao dựa trên tên (do ký tự đại diện)


  1. [Python 3]: đường dẫn lớp. Đường dẫn ( * phân đoạn đường dẫn ) ( Python 3.4 +, cổng lùi : [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ú :

    • Đây là một cách để đạt được mục tiêu của chúng tôi
    • Đó là phong cách xử lý đường dẫn OOP
    • Cung cấp nhiều chức năng


  1. [Python 2]: dircache.listdir (path) (chỉ Python 2 )

    • Tuy nhiên, theo [GitHub]: python / cpython - (2.7) cpython / Lib / dircache.py , nó chỉ là một trình bao bọc (mỏng) os.listdirvới bộ nhớ đệm


    def 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
    


  1. [man7]: OPENDIR (3) / [man7]: READDIR (3) / [man7]: CLOSEDIR (3) qua [Python 3]: ctypes - Thư viện hàm ngoại cho Python ( cụ thể cho POSIX )

    ctypes là một thư viện hàm ngoại cho Python. Nó cung cấp các kiểu dữ liệu tương thích với C, và cho phép gọi các hàm trong DLL hoặc thư viện chia sẻ. Nó có thể được sử dụng để bọc các thư viện này bằng 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ú :

    • Nó tải ba hàm từ libc (được tải trong quy trình hiện tại) và gọi chúng (để biết thêm chi tiết, hãy kiểm tra [SO]: Làm cách nào để kiểm tra xem tệp có tồn tại mà không có ngoại lệ hay không? (@ CristiFati's answer) - ghi chú cuối cùng từ mục # 4. ). Điều đó sẽ đặt phương pháp này rất gần với Python / C cạnh
    • LinuxDirent64 là đại diện ctypes của struct dirent64 từ [man7]: dirent.h (0P) (các hằng số DT_ cũng vậy ) từ máy của tôi: Ubtu 16 x64 ( 4.10.0-40-genericlibc6-dev: amd64 ). Trên các phiên bản / phiên bản khác, định nghĩa cấu trúc có thể khác và nếu vậy, bí danh ctypes nên được cập nhật, nếu không, nó sẽ mang lại Hành vi không xác định
    • Nó trả về dữ liệu ở 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á đơn giản
    • Mọi thứ đều có thể thực hiện được trên Win , dữ liệu (thư viện, hàm, cấu trúc, hằng số, ...) khác nhau


    Đầu ra :

    [[email protected]:~/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']]
    


  1. [ActiveState.Docs]: win32file.FindFilesW ( Win cụ thể)

    Truy xuất danh sách các tên tệp phù hợp, sử dụng Windows Unicode API. Một 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.FindFilesWlà một phần của [GitHub]: mhammond / PyWin32 - Python cho Windows (PyWin32) Extensions , mà là một Python wrapper trên WINAPI s
    • Liên kết tài liệu là từ ActiveState , vì tôi không tìm thấy bất kỳ tài liệu chính thức nào của PyWin32


  1. Cài đặt một số gói bên thứ ba (khác) thực hiện thủ thuật
    • Rất có thể, sẽ dựa vào một (hoặc nhiều) điều trên (có thể với các tùy chỉnh nhỏ)


Ghi chú :

  • Mã có nghĩa là có thể 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:

    • nền tảng ( Nix , Win ,)
    • Phiên bản Python (2, 3,)
  • 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ác "công cụ" được sử dụng rất linh hoạt theo hướng này

  • os.listdiros.scandirsử dụng opendir / readdir / closedir ( [MS.Docs]: FindFirstFileW function / [MS.Docs]: FindNextFileW function / [MS.Docs]: FindClose function ) (via [GitHub]: python / cpython - (master) cpython / Mô-đun / posixmodule.c )

  • win32file.FindFilesWcũng sử dụng các hàm đó ( dành riêng cho Win ) (thông qua [GitHub]: mhammond / pywin32 - (master) pywin32 / win32 / src / win32file.i )

  • _get_dir_content (từ điểm số 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)

    • Một số lọc nâng cao (thay vì chỉ tệp so với dir) có thể được thực hiện: ví dụ: đối số include_folders có thể được thay thế bằng một đối số khác (ví dụ: filter_func ) sẽ là một hàm lấy đường dẫn làm đối số: filter_func=lambda x: True(điều này không loại bỏ bất cứ thứ gì) và bên trong _get_dir_content đại loại như: if not filter_func(entry_with_path): continue(nếu hàm không thành công với 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
  • Xin chào! Vì đệ quy được sử dụng, tôi phải đề cập rằng tôi đã thực hiện một số bài kiểm tra 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 giá trị ở đâu đó trong phạm vi ( 990 .. 1000) ( recursionlimit - 1000 (mặc định)), tôi đã nhận 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 FS , vì vậy tôi không biết liệu điều đó có khả thi 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 lĩnh vực này (tôi có thể tăng nó lên bao nhiêu trước khi cũng phải tăng ngăn xếp ở cấp hệ điều hành ), nhưng về lý thuyết thì sẽ luôn có khả năng thất bại, nếu độ sâu dir lớn hơn độ sâu đệ quy cao nhất có thể có (trên máy đó)

  • Các mẫu mã chỉ dành cho mục đích minh họa. Điều đó có nghĩa là tôi đã không tính đến việc xử lý lỗi (tôi không nghĩ rằng có bất kỳ khối thử / ngoại trừ / else / cuối cùng nào ), vì vậy mã không mạnh mẽ (lý do là: để giữ cho nó đơn giản và ngắn gọ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

Các cách tiếp cận khác:

  1. Chỉ sử dụng Python làm trình bao bọc

    • Mọi thứ được thực hiện bằng công nghệ khác
    • Công nghệ đó được gọi từ Python
    • 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 :

      • Sử dụng Python (hoặc bất kỳ ngôn ngữ lập trình nào cho vấn đề đó) để thực hiện các lệnh shell (và phân tích cú pháp đầu ra của chúng)
      • Một số coi đây là một vụ hack gọn gàng
      • Tôi coi nó giống như một cách giải quyết khập khiễng ( gainarie ), vì mỗi hành động được thực hiện từ shell ( cmd trong trường hợp này) và do đó không liên quan gì đến Python .
      • Lọc ( grep/ findstr) hoặc định dạng đầu ra có thể được thực hiện ở cả hai phía, 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.systemthay 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 nên được 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 / phiên bản hệ điều hành , thì mã phân tích cú pháp cũng nên được điều chỉnh; chưa kể đến sự khác biệt giữa các ngôn ngữ).

48
ArtOfWarfare 2014-07-10 01:43.

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 khớp mẫu với *s.

Nhưng như những người khác đã chỉ ra trong các bình luận, glob()có thể vấp phải những hướng chém không nhất quán. Để trợ giúp điều đó, tôi khuyên bạn nên sử dụng các hàm join()expanduser()trong os.pathmô-đun, và có lẽ cả getcwd()hàm trong osmô-đun.

Như 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 thật tồi tệ - đường dẫn đã được mã hóa cứng và sẽ chỉ hoạt động trên Windows giữa tên ổ đĩa và tên \đượ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'))

Cách trên hoạt động tốt hơn, nhưng nó phụ thuộc vào tên thư mục Usersthường thấy trên Windows và không thường thấy trên các hệ điều hành khác. Nó cũng phụ thuộc vào việc 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à có một chút gì đó khác biệ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 sẽ giúp bạn thấy được sức mạnh của một vài hàm mà bạn có thể tìm thấy trong các mô-đun thư viện Python chuẩn.

37
Apogentus 2014-06-11 06:16.
def list_files(path):
    # returns a list of names (with extension, without full path) of all files 
    # in folder path
    files = []
    for name in os.listdir(path):
        if os.path.isfile(os.path.join(path, name)):
            files.append(name)
    return files 
24
Yauhen Yakimovich 2014-04-11 04:09.

Nếu bạn đang tìm kiếm một triển khai Python của find , thì đây là 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 một gói PyPI từ nó và cũng có một kho lưu trữ GitHub . Tôi hy vọng rằng ai đó thấy nó có khả năng hữu ích cho mã này.

14
Andy Fedoroff 2019-01-10 00:11.

Để có kết quả tốt hơn, bạn có thể sử dụng listdir()phương thức của osmô-đun cùng với trình tạo (trình tạo là một 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ã:

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ề Truenếu mục nhập đã cho là một tệp. Và yieldtoán tử thoát khỏi func nhưng vẫn giữ trạng thái hiện tại của nó và nó chỉ trả về tên của mục nhập đượ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 lại hàm máy phát điện.

11
The2ndSon 2014-06-14 06:26.

Trả về danh sách các đường dẫn tệp tuyệt đối, không đệ quy vào 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))]
10
pah8J 2018-06-20 02:03.
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.

10
fralau 2019-03-24 21:07.

Một người thầy 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 điều gì đó, không có cách nào trong số đó là tốt cho mọi 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 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 cần đi vào thư mục con. Do đó, chúng tôi muốn một hàm trả về danh sách các 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 trước 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 tổng quát hóa với các biểu thức chính quy (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 dính vào phần đầu hoặc phần cuối của tên tệp).

6
shantanoo 2016-12-02 21:01.

Sử dụng máy phát điện

import os
def get_files(search_path):
     for (dirpath, _, filenames) in os.walk(search_path):
         for filename in filenames:
             yield os.path.join(dirpath, filename)
list_files = get_files('.')
for filename in list_files:
    print(filename)
5
fhchl 2018-03-29 02:20.

Một biến thể rất dễ đọc khác cho Python 3.4+ đang 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 kiếm các tệp nguồn Python không phải là các liên kết tượng trưng, ​​cũng như trong tất cả các thư mục con:

[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]
4
chris-piekarski 2018-10-19 16:34.

Đối với python2:

pip install rglob

sau đó làm

import rglob
file_list=rglob.rglob("/home/base/dir/", "*")
print file_list
3
MarredCheese 2017-12-08 10:10.

Đây là chức năng mục đích chung của tôi cho việc này. Nó trả về danh sách các đường dẫn tệp thay vì tên tệp vì tôi thấy điều đó hữu ích hơn. Nó có một vài đối số tùy chọn làm cho nó trở nên linh hoạt. Ví dụ, 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)]
2
Vinodh Krishnaraju 2017-12-12 07:51.

Tôi sẽ cung cấp một mẫu một lớp lót trong đó có thể cung cấp đường dẫn và loại tệp làm đầu vào. Mã trả về 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 cần được trả lại. Thao tác 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 và đường dẫn nguồn nếu cần.

2
shaji 2012-07-26 00:25.

dircache là "Không được 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

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Đây là Tổng thống Trump đe dọa 'trợ cấp' xe điện của GM vì đóng cửa nhà máy

Đây là Tổng thống Trump đe dọa 'trợ cấp' xe điện của GM vì đóng cửa nhà máy

Trump và Giám đốc điều hành GM Mary Barra vào năm 2017. Kể từ khi tin tức nổ ra ngày hôm qua rằng General Motors đang cắt giảm việc làm ở Bắc Mỹ để chuẩn bị cho tương lai điện / xe tự hành / khủng khiếp có thể xảy ra của chúng tôi, gần như tất cả mọi người đã tự hỏi: Tổng thống Trump, người đã vận động tranh cử trên một nền tảng sẽ như thế nào của việc mang lại và duy trì việc làm ô tô của Mỹ, phải nói gì về điều này? Bây giờ chúng ta biết.

Bản vá lỗi tiếp theo của Fallout 76 sẽ mang lại một số bản sửa lỗi cần thiết

Bản vá lỗi tiếp theo của Fallout 76 sẽ mang lại một số bản sửa lỗi cần thiết

Bethesda cho biết ngày hôm nay trên Reddit, Fallout 76 sẽ có một bản vá lớn khác vào ngày 4 tháng 12, sẽ bắt đầu cố gắng khắc phục một số vấn đề lớn hơn của trò chơi. Ngoài ra, công ty cho biết họ có kế hoạch giao tiếp nhiều hơn trong tương lai về những gì nhóm Fallout 76 đang làm việc và khi nào các bản cập nhật mới cho trò chơi sẽ ra mắt.

Mạng lưới bệnh viện Công giáo sẽ không cho phép nhân viên phá thai tại phòng khám ngoài giờ làm việc

Mạng lưới bệnh viện Công giáo sẽ không cho phép nhân viên phá thai tại phòng khám ngoài giờ làm việc

Bạn có biết rằng một trong sáu bệnh nhân ở bệnh viện ở Hoa Kỳ được điều trị tại một cơ sở Công giáo? Và bạn có biết rằng quyền sở hữu của Công giáo hạn chế sâu sắc việc thiết lập các thủ tục y tế có thể được thực hiện trong các bệnh viện này, rõ ràng nhất là khi nói đến chăm sóc sức khỏe sinh sản? Bây giờ NPR báo cáo rằng sự gia tăng của các bệnh viện thuộc Công giáo đang gây khó khăn hơn cho các bác sĩ — những người bị cấm bởi các quy định do Hoa Kỳ viết.

Khói từ đám cháy rừng ở California đã đến tận thành phố New York

Khói từ đám cháy rừng ở California đã đến tận thành phố New York

Đường chân trời San Francisco bị che khuất bởi khói và khói mù do cháy rừng phía sau Đảo Alcatraz, Thứ Tư, ngày 14 tháng 11 năm 2018, ở San Francisco.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language