ZetCode

Python os.listdir 函数

上次修改时间:2025 年 4 月 11 日

本综合指南探讨 Python 的 os.listdir 函数,该函数列出目录内容。 我们将介绍基本用法、路径处理、过滤结果和实用的文件系统操作。

基本定义

os.listdir 函数返回一个列表,其中包含目录中条目的名称。 该列表的顺序是任意的,并且不包括特殊条目 '.' 和 '..'。

主要参数:path(要列出的目录,默认为当前目录)。 返回一个字符串列表,表示目录内容。 对于无效路径,引发 OSError。

基本目录列表

os.listdir 最简单的用法是列出当前目录的内容。 本示例演示了基本用法和结果处理。

basic_listing.py
import os

# List current directory contents
contents = os.listdir()
print("Current directory contents:")
for item in contents:
    print(item)

# List specific directory
target_dir = "/tmp"
print(f"\nContents of {target_dir}:")
try:
    for item in os.listdir(target_dir):
        print(item)
except FileNotFoundError:
    print(f"Directory {target_dir} not found")
except PermissionError:
    print(f"No permission to access {target_dir}")

此示例首先列出当前目录,然后尝试列出 /tmp。 它包括针对常见目录访问问题的基本错误处理。

输出显示不带完整路径的文件名。 对于绝对路径,请将 os.path.join 与目录路径一起使用。

按扩展名筛选文件

我们可以将 os.listdir 与字符串操作结合起来,按扩展名过滤文件。 此示例查找目录中的所有 Python 文件。

filter_by_extension.py
import os

def find_py_files(directory):
    """Return list of .py files in directory"""
    py_files = []
    for filename in os.listdir(directory):
        if filename.endswith('.py'):
            py_files.append(filename)
    return py_files

# Example usage
project_dir = "src"
py_files = find_py_files(project_dir)
print(f"Python files in {project_dir}:")
for py_file in py_files:
    print(py_file)

# Using list comprehension
py_files = [f for f in os.listdir(project_dir) if f.endswith('.py')]
print(f"\nFound {len(py_files)} Python files")

该函数扫描目录并仅返回 .py 文件。 该示例显示了传统循环和列表推导方法。

对于不区分大小写的匹配,请在检查扩展名之前将文件名转换为小写。

获取文件元数据

我们可以将 os.listdiros.stat 结合起来以获取文件元数据。 本示例显示文件大小和修改时间。

file_metadata.py
import os
import time

def list_files_with_metadata(directory):
    """Print files with size and modification time"""
    print(f"Contents of {directory} with metadata:")
    for filename in os.listdir(directory):
        filepath = os.path.join(directory, filename)
        if os.path.isfile(filepath):  # Skip directories
            stat = os.stat(filepath)
            size = stat.st_size
            mtime = time.ctime(stat.st_mtime)
            print(f"{filename:20} {size:8} bytes  modified {mtime}")

# Example usage
list_files_with_metadata(".")

此脚本列出每个文件及其大小和上次修改时间。 os.path.join 创建正确的路径,而 os.stat 检索文件元数据。

该示例使用 os.path.isfile 过滤掉目录,以便只关注文件。

递归目录列表

虽然 os.listdir 仅列出一个目录,但我们可以将其与 os.walk 结合使用以进行递归列表。 本示例演示了两种方法。

recursive_listing.py
import os

def list_recursive(directory):
    """Recursively list directory contents using os.listdir"""
    for root, dirs, files in os.walk(directory):
        print(f"\nDirectory: {root}")
        print("Subdirectories:")
        for dirname in dirs:
            print(f"  {dirname}")
        print("Files:")
        for filename in files:
            print(f"  {filename}")

# Simple recursive alternative
def simple_recursive(directory, indent=0):
    """Simple recursive listing using only os.listdir"""
    items = os.listdir(directory)
    for item in items:
        full_path = os.path.join(directory, item)
        print("  " * indent + item)
        if os.path.isdir(full_path):
            simple_recursive(full_path, indent + 1)

# Example usage
print("Using os.walk:")
list_recursive(".")

print("\nUsing recursive os.listdir:")
simple_recursive(".")

第一个函数使用 os.walk 进行高效的递归列表。 第二个函数显示仅使用 os.listdir 的手动递归方法。

手动方法更简单,但对于深度目录树效率较低。

对目录内容进行排序

os.listdir 按任意顺序返回项目。 本示例演示了目录内容的各种排序技术。

sorted_listing.py
import os

def list_sorted(directory):
    """List directory contents sorted different ways"""
    items = os.listdir(directory)
    
    print("Alphabetical order:")
    for item in sorted(items):
        print(f"  {item}")
    
    print("\nReverse alphabetical:")
    for item in sorted(items, reverse=True):
        print(f"  {item}")
    
    print("\nBy size (smallest first):")
    sized_items = [(os.path.getsize(os.path.join(directory, f)), f) for f in items]
    for size, item in sorted(sized_items):
        print(f"  {item:20} {size:8} bytes")
    
    print("\nBy modification time (newest first):")
    timed_items = [(os.path.getmtime(os.path.join(directory, f)), f) for f in items]
    for mtime, item in sorted(timed_items, reverse=True):
        print(f"  {item}")

# Example usage
list_sorted(".")

这演示了按字母顺序、反向字母顺序、基于大小和基于修改时间排序。 每种方法都使用不同的键函数。

对于大型目录,请考虑使用生成器表达式而不是创建完整的元数据列表。

处理隐藏文件

类 Unix 系统会隐藏以 '.' 开头的文件。 本示例演示了如何在目录列表中过滤或包含隐藏文件。

hidden_files.py
import os

def list_hidden(directory, show_hidden=False):
    """List directory contents with hidden file control"""
    items = os.listdir(directory)
    
    if not show_hidden:
        items = [f for f in items if not f.startswith('.')]
    
    print(f"Contents of {directory} (hidden {'shown' if show_hidden else 'hidden'}):")
    for item in items:
        print(f"  {item}")

# Example usage
print("Normal listing (hidden files excluded):")
list_hidden(".")

print("\nIncluding hidden files:")
list_hidden(".", show_hidden=True)

# Windows hidden files (system/hidden attributes)
if os.name == 'nt':
    import win32api, win32con
    def is_hidden_win(filepath):
        attrs = win32api.GetFileAttributes(filepath)
        return attrs & (win32con.FILE_ATTRIBUTE_HIDDEN | win32con.FILE_ATTRIBUTE_SYSTEM)
    
    print("\nWindows hidden files:")
    for item in os.listdir("."):
        full_path = os.path.join(".", item)
        if is_hidden_win(full_path):
            print(f"  {item} (hidden)")

主函数过滤 Unix 隐藏文件。 特定于 Windows 的部分演示了如何使用 Windows API 属性检测隐藏文件。

跨平台应用程序应处理点文件和 Windows 隐藏属性,以实现完整的隐藏文件检测。

与其他方法进行比较

Python 提供了几种列出目录内容的方法。 本示例将 os.listdirglobpathlib 进行比较。

alternatives.py
import os
import glob
from pathlib import Path

directory = "."

print("Using os.listdir:")
for item in os.listdir(directory):
    print(f"  {item}")

print("\nUsing glob.glob:")
for item in glob.glob(os.path.join(directory, "*")):
    print(f"  {os.path.basename(item)}")

print("\nUsing pathlib.Path:")
for item in Path(directory).iterdir():
    print(f"  {item.name}")

print("\nFiltering with glob:")
py_files = glob.glob(os.path.join(directory, "*.py"))
print(f"Found {len(py_files)} Python files")

print("\nPathlib with pattern matching:")
py_files = list(Path(directory).glob("*.py"))
print(f"Found {len(py_files)} Python files")

这显示了使用不同 Python 模块的等效目录列表操作。 每个都有不同的优点和用例。

pathlib(Python 3.4+)提供面向对象的接口,而 glob 提供内置的模式匹配功能。

性能注意事项

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 我从 2007 年开始撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程