Python os.mkdir 函数
上次修改时间:2025 年 4 月 11 日
本综合指南探讨 Python 的 os.mkdir 函数,该函数用于在文件系统中创建目录。我们将介绍基本用法、错误处理、路径规范和权限模式。
基本定义
os.mkdir 函数使用指定的名称创建一个目录。它是 Python os 模块的一部分,该模块提供操作系统接口。
关键参数:path(要创建的目录)、mode(权限,默认 0o777)和 dir_fd(可选目录文件描述符)。失败时引发 OSError。
创建基本目录
os.mkdir 最简单的用法是在当前工作目录中创建一个单独的目录。此示例演示了基本目录创建。
import os
# Create a single directory
dir_name = "my_directory"
try:
os.mkdir(dir_name)
print(f"Directory '{dir_name}' created successfully")
except FileExistsError:
print(f"Directory '{dir_name}' already exists")
except OSError as error:
print(f"Error creating directory '{dir_name}': {error}")
此代码尝试创建一个目录并处理常见错误。如果目录存在,则会发生 FileExistsError,而 OSError 会捕获其他错误。
在处理文件系统操作时,始终处理异常,因为可能会出现很多问题(权限、无效名称等)。
创建具有特定权限的目录
mode 参数控制类 Unix 系统上的目录权限。此示例演示了如何在创建目录时设置显式权限。
import os
dir_name = "private_dir"
# Set permissions to owner read/write/execute only
mode = 0o700 # Equivalent to rwx------
try:
os.mkdir(dir_name, mode)
print(f"Private directory '{dir_name}' created with mode {oct(mode)}")
# Verify permissions
stat_info = os.stat(dir_name)
print(f"Actual directory permissions: {oct(stat_info.st_mode & 0o777)}")
except OSError as e:
print(f"Error creating directory: {e}")
这将创建一个具有限制性权限的目录(只有所有者才能访问)。该模式以八进制表示法指定(0o700 表示仅所有者访问)。
请注意,实际权限可能受到进程的 umask 设置的影响,该设置会屏蔽掉某些权限位。
创建嵌套目录
os.mkdir 只能一次创建一个目录级别。对于嵌套路径,您需要依次创建每个级别,或使用 os.makedirs。
import os
nested_path = "parent/child/grandchild"
# This will fail because parent directories don't exist
try:
os.mkdir(nested_path)
print("Created nested directory")
except FileNotFoundError:
print("Parent directories don't exist - need to create them first")
# Correct approach for nested directories
try:
os.makedirs(nested_path)
print("Successfully created nested directory structure")
except OSError as e:
print(f"Error creating directories: {e}")
第一次尝试失败,因为中间目录不存在。第二个使用 os.makedirs,它创建所有必需的父目录。
对于您控制环境的简单情况,os.makedirs 通常比多个 os.mkdir 调用更方便。
创建具有绝对路径的目录
os.mkdir 适用于相对路径和绝对路径。此示例演示了如何使用绝对路径规范创建目录。
import os
# Create directory in user's home directory
home_dir = os.path.expanduser("~")
new_dir = os.path.join(home_dir, "my_app_data")
try:
os.mkdir(new_dir)
print(f"Created directory at absolute path: {new_dir}")
# Verify the directory exists
if os.path.isdir(new_dir):
print("Directory verification successful")
except PermissionError:
print("Permission denied - cannot create directory in home folder")
except OSError as e:
print(f"Error creating directory: {e}")
这通过构造绝对路径在用户的主文件夹中创建一个目录。os.path.expanduser 处理跨平台主目录。
在需要维护特定目录结构的应用程序中,使用绝对路径通常比相对路径更可靠。
处理目录创建竞争条件
当多个进程可能创建相同的目录时,我们需要处理竞争条件。此示例显示了一种线程安全的方法。
import os
import time
from threading import Thread
shared_dir = "shared_directory"
def create_dir():
try:
os.mkdir(shared_dir)
print(f"{os.getpid()} created the directory")
except FileExistsError:
print(f"{os.getpid()} directory already exists")
# Simulate multiple processes trying to create the same directory
threads = []
for i in range(5):
t = Thread(target=create_dir)
threads.append(t)
t.start()
time.sleep(0.1) # Increase chance of race condition
for t in threads:
t.join()
print("All threads completed")
这模拟了多个进程尝试同时创建相同的目录。只有一个会成功创建它,其他进程会看到它存在。
FileExistsError 异常是处理此竞争条件的正确方法,而不是首先检查是否存在,这可能会导致 TOCTOU 问题。
创建具有 Unicode 名称的目录
os.mkdir 在大多数现代系统上支持 Unicode 目录名称。此示例演示了如何创建具有非 ASCII 字符的目录。
import os
# Directory names with various Unicode characters
dir_names = [
"文档", # Chinese for "documents"
"ελληνικά", # Greek
"Русский", # Russian
"日本語", # Japanese
"مرحبا" # Arabic
]
for name in dir_names:
try:
os.mkdir(name)
print(f"Created directory: {name}")
except OSError as e:
print(f"Failed to create {name}: {e}")
# Clean up
for name in dir_names:
try:
os.rmdir(name)
except:
pass
这将创建具有各种脚本中名称的目录。大多数现代文件系统都支持 Unicode 名称,但在某些系统上可能存在限制。
如果您的应用程序需要处理国际化的目录名称,请始终测试 Unicode 支持。
创建临时目录
对于临时目录,Python 的 tempfile 模块通常更好,但您可以将 os.mkdir 与唯一名称一起使用。
import os
import time
import uuid
# Create a temporary directory with unique name
temp_dir = f"temp_{int(time.time())}_{uuid.uuid4().hex[:8]}"
try:
os.mkdir(temp_dir)
print(f"Created temporary directory: {temp_dir}")
# Use the directory...
with open(os.path.join(temp_dir, "log.txt"), "w") as f:
f.write("Temporary data")
# Clean up
os.remove(os.path.join(temp_dir, "log.txt"))
os.rmdir(temp_dir)
print("Temporary directory cleaned up")
except OSError as e:
print(f"Error working with temporary directory: {e}")
这使用时间戳和 UUID 创建一个唯一命名的临时目录。请记住在不再需要临时目录时清理它们。
对于生产代码,请考虑使用 tempfile.mkdtemp(),它可以更可靠地处理清理和安全方面的问题。
安全注意事项
- 权限处理:注意目录权限
- 路径清理:验证路径以防止目录遍历
- 竞争条件:处理目录可能出现/消失的情况
- 符号链接:注意与符号链接相关的安全问题
- 错误处理:始终处理潜在的文件系统错误
最佳实践
- 使用 try/except:始终处理潜在错误
- 检查是否存在:如果需要,首先使用 os.path.exists
- 首选 makedirs:对于嵌套路径,使用 os.makedirs
- 设置权限:显式设置安全敏感目录的模式
- 清理:完成后删除临时目录
资料来源
作者
列出所有 Python 教程。