it-swarm-vi.com

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

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 list?

3472
duhhunjonn

os.listdir() sẽ giúp bạn có mọi thứ trong thư mục - tệp và thư mục.

Nếu bạn muốn chỉ 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() sẽ mang lại hai danh sách cho mỗi thư mục mà nó truy cập - chia thành các tệp và thư mục 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

Và cuối cùng, như ví dụ đó cho thấy, thêm một danh sách vào danh sách khác, bạn có thể sử dụng .extend() hoặc

>>> q = [1, 2, 3]
>>> w = [4, 5, 6]
>>> q = q + w
>>> q
[1, 2, 3, 4, 5, 6]

Cá nhân, tôi thích .extend()

3380
pycruft

Tôi thích sử dụng mô-đun glob , 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', .... ]
1351
adamk
import os
os.listdir("somedirectory")

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

645
sepp2k

Nhận danh sách các tệp với Python 2 và 3


Tôi cũng đã thực hiện một video ngắn ở đây:   Python: cách lấy danh sách tệp trong thư mục


os.listdir ()

hoặc ..... cách lấy tất cả các tệp (và thư mục) trong thư mục hiện tại (Python 3)

Cách đơn giản nhất để có tệp trong thư mục hiện tại trong Python 3 là đây. Nó thực sự đơn giản; sử dụng mô-đun os và chức năng listdir() và bạn sẽ có tệp trong thư mục đó (và các thư mục cuối cùng có trong thư mục, nhưng bạn sẽ không có tệp trong thư mục con, vì bạn có thể sử dụng đi bộ trễ rồi).

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

Sử dụng toàn cầu

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. Hãy xem ví dụ sau :

import glob

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

Sử dụng hiểu danh sách

import glob

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

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 mô-đun os.path có tên _getfullpathname, đặt tệp mà bạn nhận được từ os.listdir() làm đối số. Có nhiều cách khác để có đường dẫn đầy đủ, như chúng tôi sẽ kiểm tra sau (tôi đã thay thế, như được đề xuất bởi mexmex, _getfullpathname bằng abspath).

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

Nhận 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 ".docx" in file:
            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('.')
>>> 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')
>>> 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]
>>> arr
['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']

mô-đun toàn cầu - tất cả các tệp

import glob
print(glob.glob("*"))

out:['content', 'start.py']

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)

>output

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]

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

toàn cầu - chỉ nhận các tệp txt

>>> import glob
>>> x = glob.glob("*.txt")
>>> x
['ale.txt', 'alunni2015.txt', 'assenze.text.txt', 'text2.txt', 'untitled.txt']

Sử dụng toàn cầu để có được đườ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 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 khác của toàn cầu

Nếu tôi muốn tất cả các tập tin trong thư mục:

>>> x = glob.glob("*")

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)

> output

['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

Nếu bạn muốn sử dụng danh sách hiểu

>>> flist = [p for p in pathlib.Path('.').iterdir() if p.is_file()]

* Bạn cũng có thể sử dụng chỉ 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)

đầu ra:

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)

>>> 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]
>>> 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ở đi

>>> import os
>>> x = [f.name for f in os.scandir() if f.is_file()]
>>> 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
>>>

Vd 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"))

> output

>'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("------------------------")
        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')


> Output

_compiti18\Compito Contabilità 1\conti.txt
_compiti18\Compito Contabilità 1\modula4.txt
_compiti18\Compito Contabilità 1\moduloa4.txt
------------------------
==> Found in: `_compiti18` : 3 files

Vd 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 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")    

Một chức năng để tìm kiếm một loại tập tin nhất định

import os

def searchfiles(extension='.ttf'):
    "Create a txt file with all the file of a type"
    with open("file.txt", "w", encoding="utf-8") as filewrite:
        for r, d, f in os.walk("C:\\"):
            for file in f:
                if file.endswith(extension):
                    filewrite.write(f"{r + file}\n")

# looking for ttf file (fonts)
searchfiles('ttf')
489
Giovanni Gianni

Một giải pháp một dòng để nhận chỉ 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]]
149
Remi

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")

  • Đườ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 là "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 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

117
Johnny

Kể từ phiên bản 3.4, có tích hợp iterators 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 đích của pathlib library 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 hoạt động chung 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.

70
SzieberthAdam

Ghi chú sơ bộ

  • Mặc dù có sự khác biệt rõ ràng giữa các điều khoản thư mục trong văn bản câu hỏi, một số người có thể lập luận rằng các thư mục thực sự là các tệp đặc biệt
  • Câu lệnh: " tất cả các tệp của một thư mục " có thể được hiểu theo hai cách: [.__.]
    1. Tất cả con cháu trực tiếp (hoặc cấp 1) chỉ
    2. Tất cả các hậu duệ trong toàn bộ cây thư mục (bao gồm cả những người trong thư mục con)
  • Khi câu hỏi được hỏi, tôi tưởng tượng rằng Python 2 , là LTS phiên bản, tuy nhiên các mẫu mã sẽ được chạy bởi Python 3 (. 5 ) (Tôi sẽ giữ chúng dưới dạng Python 2 tuân thủ càng tốt, đồng thời, bất kỳ mã nào thuộc về Python mà tôi sẽ đăng, là từ v3.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 ":

    • Trong các phiên bản trước Python 2.2 , các chuỗi (iterables) chủ yếu được đại diện bởi các danh sách (bộ, bộ, ...)
    • Trong Python 2.2 , khái niệm trình tạo ( [Python.Wiki]: Trình tạo ) - lịch sự của [Python 3]: Tuyên bố lợi suất ) - đã được giới thiệu. 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ề/làm việc với danh sách
    • Trong Python 3 , trình tạo là hành vi mặc định
    • Không chắc chắn nếu trả về danh sách vẫn là bắt buộc (hoặc trình tạo cũng sẽ làm như vậy), nhưng việc chuyển một trình tạo đến hàm tạo , sẽ tạo một danh sách từ đó (và cả tiêu thụ nó). Ví dụ dưới đây minh họa sự khác biệt trên hàm [Python 3]: map (, có thể lặp lại, ... )
    _>>> 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à cho Win , nhưng tôi đang sử dụng cùng một cây trên Lnx cũng vậy):

    _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 lập trình:

  1. [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 __== "__main__":
        main()
    _

    Ghi chú :

    • Có hai cách triển khai: [.__.]
      • Một cái sử dụng máy phát điện (tất nhiên ở đây có vẻ như vô dụng, vì tôi ngay lập tức chuyển đổi kết quả thành một danh sách)
      • Kiểu 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 bắt đầu bằng một gạch dưới ( _ ): "private" (không nên được gọi trực tiếp) - đó là tất cả công việc
      • Công khai (bao bọc so với trước): nó chỉ loại bỏ đường dẫn ban đầu (nếu cần) từ 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ể đi kèm vào thời điểm này
    • Về hiệu suất, các trình tạo thường nhanh hơn một chút (xem xét cả hai tạo lần lặp lần), 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 mức độ thân thiện với hiệu suất như thế nào
    • Chơi với các đối số để 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]: os. scandir ( path = '.' ) ( Python 3.5 +, backport: [PyPI]: scandir =)

    Trả về một iterator của os.DirEntry các đối tượng tương ứng với các mục trong thư mục được cung cấp bởi path . Các mục được sinh ra 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 vì listdir () có thể 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ì os.DirEntry = các đối tượng phơi bày thông tin này nếu hệ điều hành cung cấp nó khi quét một thư mục. Tất cả các phương thức os.DirEntry có thể thực hiện cuộc gọi hệ thống, nhưng is_dir ()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ú :

    • 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 hơn ic Python (và trong một số trường hợp, nhanh hơn)


  1. [Python 3]: os. walk ( 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ắt nguồn từ thư mục top (bao gồm top ), nó mang lại 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ú :

    • Trong các cảnh, nó sử dụng _os.scandir_ (_os.listdir_ trên các phiên bản cũ hơn)
    • Nó thực hiện việc nâng vật nặng bằng cách định kỳ trong các thư mục con


  1. [Python 3]: global. 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ó thể trống các tên đường dẫn 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 họ hàng (như _../../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 bao gồm trong các kết quả (như trong Shell).
    [.__.] ...
    [.__.] Đã thay đổi trong phiên bản 3.5 : Hỗ trợ cho các quả cầu đệ quy bằng cách sử dụng _**_ lu.


    _>>> 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 cây lớn (đặc biệt là nếu đệ quy đang bật), 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]: class pathlib. Đường dẫn ( * pathsegments ) ( 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ú :

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


  1. [Python 2]: dircache.listdir (đường dẫn) ( Python 2 chỉ có)


    _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]: ĐÃ ĐÓNG CỬA (3) qua - [Python 3]: ctypes - Thư viện hàm ngoại cho Python (POSIX cụ thể)

    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 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 __== "__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 kiểm tra [SO]: Làm cách nào để kiểm tra xem một tệp có tồn tại không không có ngoại lệ? (câu trả lời của @ CristiFati) - ghi chú cuối cùng từ mục # 4. ) . Điều đó sẽ đặt cách tiếp cận này rất gần với Python /C
    • LinuxDirent64 là đại diện ctypes của struct dirent64 từ [ man7]: dirent.h (0P) (các hằng số DT _ ) từ máy của tôi: Ubtu 16 x64 ( 4.10.0-40-generic libc6-dev: AMD64 ). Trên các hương vị/phiên bản khác, định nghĩa cấu trúc có thể khác nhau và nếu vậy, bí danh ctypes cầ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 ở định dạng _os.walk_ 's. 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ỏ
    • Mọi thứ đều có thể thực hiện được trên Win cũng vậy, 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ể)

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


  1. Cài đặt một số gói của bên thứ ba (khác) thực hiện thủ thuật [.__.]
    • Nhiều khả năng, sẽ dựa vào một (hoặc nhiều hơn) ở 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 , Giành chiến thắng ,)
    • 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ông cụ" được sử dụng linh hoạt theo hướng này

  • _os.listdir_ và _os.scandir_ sử dụng opendir / readdir / closeir ( [MS.Docs]: Hàm FindFirstFileW / [MS.Docs]: Hàm FindNextFileW / [MS.Docs]: Hàm FindClose =) (thông qua [GitHub]: python/cpython - (master) cpython/Modules/posixmodule.c )

  • _win32file.FindFilesW_ cũng sử dụng các hàm đó ( Win cụ thể) (thông qua [GitHub]: mhammond/pywin32 - (chính) pywin32/win32/src/win32file .i )

  • _ get_dir_content (từ điểm # 1. ) có thể được thực hiện bằng bất kỳ cách tiếp cận nào trong số này (một số sẽ đòi hỏi nhiều công việc hơn và một số ít hơn)

    • Một số bộ 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 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
  • Nota bene! Kể từ khi sử dụng đệ quy, 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) ( 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 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 recursionlimit 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 ngăn xếp ở mức OS), 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 cao nhất có thể recursionlimit (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 khoản (Tôi không nghĩ có bất kỳ thử / ngoại trừ / khác / cuối cùng khối), 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 , cũng nên thêm xử lý lỗi

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ách sử dụ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ị viên 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 kết quả đầu ra của chúng)
      • Một số người coi đây là một 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ì hành động mỗi se đượ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 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, nên tránh cách tiếp cận này, vì nếu một số định dạng đầu ra lệnh hơi khác nhau giữa OS phiên bản/hương vị, 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).

52
CristiFati

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ải quyết vấn đề đó, tôi khuyên bạn cũng nên sử dụng các hàm join()expanduser() trong mô-đun os.path và có lẽ cả hàm getcwd() trong mô-đun os.

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 được tìm thấy trên Windows và không thường thấy trên các HĐH khác. Nó cũng phụ thuộc 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 sẽ 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.

47
ArtOfWarfare
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 
34
Apogentus

Nếu bạn đang tìm kiếm một triển khai Python của find , đâ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 một gói PyPI trong số đó và cũng có 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.

22
Yauhen Yakimovich

Trả lại danh sách các filepath tuyệt đối, không lặp lại 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))]
12
The2ndSon

Để có kết quả cao hơn, bạn có thể sử dụng phương thức listdir() của mô-đun os 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)

Phương thức listdir() trả về danh sách các mục nhập cho thư mục đã cho. Phương thức os.path.isfile() trả về True nếu mục nhập đã cho là một tệp. Và toán tử yield 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 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 qua chức năng của trình tạo.

Hi vọng điêu nay co ich.

10
ARGeo
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.

9
pah8J

Tôi giả sử rằng tất cả các tệp của bạn có định dạng *.txt và được lưu trữ trong một thư mục có đường dẫn data/.

Người ta có thể sử dụng global module của python để liệt kê tất cả các tệp của thư mục và thêm chúng vào danh sách có tên fnames, theo cách sau:

import glob

fnames = glob.glob("data/*.txt")  #fnames: list data type
9
Siddharth Satpathy

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 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 đối số pattern, nếu bạn không muốn các mẫu của bạn luôn bám vào đầu hoặc cuối của tên tệp).

7
fralau

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
shantanoo

Bạn có thể sử dụng mã này để lấy iterator chạy trên toàn bộ đường dẫn của tệp (Thư mục + tên tệp).

import os

def get_iterator_all_files_name(dir_path):
    for (dirpath, dirnames, filenames) in os.walk(dir_path):
        for f in filenames:
            yield os.path.join(dirpath, f)

Hoặc sử dụng nó, để có được nó trong danh sách.

import os

def get_list_all_files_name(dir_path):
    all_files_path = []

    for (dirpath, dirnames, filenames) in os.walk(dir_path):
        for f in filenames:
            all_files_path.append(os.path.join(dirpath, f))

    return all_files_path
5
yehuda corsia
# -** coding: utf-8 -*-
import os
import traceback

print '\n\n'

def start():
    address = "/home/ubuntu/Desktop"
    try:
        Folders = []
        Id = 1
        for item in os.listdir(address):
            endaddress = address + "/" + item
            Folders.append({'Id': Id, 'TopId': 0, 'Name': item, 'Address': endaddress })
            Id += 1         

            state = 0
            for item2 in os.listdir(endaddress):
                state = 1
            if state == 1: 
                Id = FolderToList(endaddress, Id, Id - 1, Folders)
        return Folders
    except:
        print "___________________________ ERROR ___________________________\n" + traceback.format_exc()

def FolderToList(address, Id, TopId, Folders):
    for item in os.listdir(address):
        endaddress = address + "/" + item
        Folders.append({'Id': Id, 'TopId': TopId, 'Name': item, 'Address': endaddress })
        Id += 1

        state = 0
        for item in os.listdir(endaddress):
            state = 1
        if state == 1: 
            Id = FolderToList(endaddress, Id, Id - 1, Folders)
    return Id

print start()
5
barisim.net

Sử dụng chức năng này nếu bạn muốn sử dụng một loại tệp khác hoặc lấy thư mục đầy đủ:

import os

def createList(foldername, fulldir = True, suffix=".jpg"):
    file_list_tmp = os.listdir(foldername)
    #print len(file_list_tmp)
    file_list = []
    if fulldir:
        for item in file_list_tmp:
            if item.endswith(suffix):
                file_list.append(os.path.join(foldername, item))
    else:
        for item in file_list_tmp:
            if item.endswith(suffix):
                file_list.append(item)
    return file_list
3
neouyghur

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()]
3
fhchl
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
2
shaji

Đâ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)]
2
MarredCheese

Đối với python2: pip cài đặt rglob

import rglob
file_list=rglob.rglob("/home/base/dir/", "*")
print file_list
1
chris-piekarski

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.

0
Vinodh Krishnaraju