Skip to main content

os

现代路径操作推荐使用 pathlib,但以下能力只有 os(及 os.path)能提供,pathlib 无法替代。

进程与工作目录

pathlib 的 Path.cwd() 只能读取当前工作目录,不能改变它。改变进程级工作目录必须用 os:

  • os.chdir(path):把当前进程的工作目录改为指定路径(影响后续所有相对路径)。
  • os.getcwd():返回当前工作目录的字符串。
  • os.curdir:当前目录符号('.'),用于表示“当前目录”。
import os

os.chdir("/tmp") # 仅 os 能做;pathlib 无 chdir
print(os.getcwd()) # 如 '/tmp'
print(os.curdir) # '.'

pathlib 没有的目录/文件操作

  • os.removedirs(path):自底向上递归删除空目录(pathlib 只有单层的 Path.rmdir(),不能一次删多级空目录)。
  • os.renames(old, new):重命名文件或目录,若目标路径的父目录不存在则自动创建(pathlib 的 Path.rename() 不会创建中间目录)。

其余如删除文件、单层建目录、多级建目录、单层删空目录、普通重命名等,pathlib 都有对应方法(如 unlink()mkdir()mkdir(parents=True)rmdir()rename()),可优先用 pathlib;需要与旧接口或字符串路径打交道的场景再保留 os。

import os

# 递归删除空目录(pathlib 做不了)
# os.removedirs("a/b/c") # 会删除 c、b、a(若均为空)

# 重命名并自动创建目标父目录(pathlib 的 rename 不会创建父目录)
# os.renames("old.txt", "dir/subdir/new.txt")

可剪枝的目录遍历:os.walk()

pathlib 有 Path.rglob() 等递归遍历,但不能在遍历过程中按目录名剪枝(例如跳过 .git__pycache__)。os.walk() 可以:在循环里修改 dirnames 列表,即可决定下一层进入哪些子目录。

  • os.walk(top): yields (根路径, 子目录名列表, 文件名列表)原地修改 dirnames 即可排除某些目录,不进入其子树。
import os

def get_files(dir_path, skip_dirs=None):
skip_dirs = set(skip_dirs or [".git", "__pycache__", "node_modules"])
for parent, dirnames, filenames in os.walk(dir_path):
# 剪枝:不进入 skip_dirs 中的目录(pathlib.rglob 无法边遍历边排除)
dirnames[:] = [d for d in dirnames if d not in skip_dirs]
for filename in filenames:
print("parent:", parent, "file:", filename)
print("full path:", os.path.join(parent, filename))

get_files(os.curdir)

系统常量

pathlib 不提供这些与平台相关的字符串常量,只能从 os 取:

  • os.linesep:当前平台的换行符(Windows '\r\n',Unix '\n')。
  • os.sep:路径分隔符(Windows '\\',Unix '/')。
  • os.pathsep:环境变量/PATH 中的分隔符(Windows ';',Unix ':')。
import os

print(repr(os.linesep)) # Windows: '\r\n';Unix: '\n'
print(repr(os.sep)) # Windows: '\\';Unix: '/'
print(repr(os.pathsep)) # Windows: ';';Unix: ':'

环境变量

pathlib 不处理环境变量。读写环境变量只能用 os:

  • os.environ:类似字典,表示当前进程的环境变量,可读可写。
  • os.getenv(key, default=None) / os.environ.get(key):读取。
  • os.putenv(key, value) / os.environ[key] = value:写入(修改只影响当前进程及子进程)。
import os

# 读取
print(os.environ.get("HOME", ""))
print(os.getenv("PATH", ""))

# 修改(仅当前进程)
os.environ["MY_VAR"] = "value"