Python 的 os 和 shutil 模块

        大家好,在日常的编程工作中,处理文件和目录是一个非常常见的任务。无论是创建、复制、移动还是删除文件,这些操作都需要我们与文件系统进行交互。在 Python 中,有两个强大的模块可以帮助我们轻松地进行文件和目录操作,它们分别是 osshutil 模块。

    os 模块提供了许多用于处理操作系统功能的函数,包括文件和目录操作、环境变量访问等。而 shutil 模块则构建在 os 模块的基础上,提供了更高级的文件操作功能,如复制、移动、删除文件以及归档和压缩等。本文将深入探讨这两个模块的使用方法,并通过示例代码和实用技巧,帮助大家更好地利用 Python 来管理文件系统。

一、介绍

        当探讨 Python 文件系统操作时,osshutil 模块是绕不开的两个关键组件。它们提供了丰富而强大的功能,使得在 Python 中进行文件和目录操作变得更加便捷和高效。下面详细介绍这两个模块的重要性、作用和功能:

1、为什么 os 和 shutil 模块在 Python 编程中如此重要?

        在实际编程中,文件和目录操作是非常常见的任务,涉及到创建、读取、写入、删除、移动、重命名等多种操作。无论是在开发桌面应用、服务器端程序、数据处理脚本还是其他类型的应用中,都会频繁地涉及到文件和目录的操作。而 Python 作为一种流行且功能强大的编程语言,提供了丰富的标准库,其中 osshutil 模块就是处理文件系统操作的重要组成部分。这两个模块的存在,使得开发者能够轻松地在 Python 中执行各种文件和目录操作任务,从而节省了大量的时间和精力。

2、两个模块的作用和功能简介

  • os 模块(Operating System Interface): os 模块提供了与操作系统进行交互的接口,包括文件和目录操作、进程管理、环境变量等。它是 Python 中最常用的标准库之一,提供了许多方便的函数和方法,使得开发者能够轻松地执行各种系统级操作。os 模块的功能包括但不限于:

    • 文件和目录操作:创建、删除、重命名、检查文件是否存在等。
    • 文件信息获取:获取文件大小、修改时间、权限等信息。
    • 目录遍历:遍历目录中的文件和子目录。
    • 环境变量操作:获取、设置、删除环境变量等。
  • shutil 模块(High-level File Operations): shutil 模块是在 os 模块的基础上构建的高级文件操作工具集,提供了一系列用于文件和目录操作的高级函数,如复制、移动、删除文件等。它通过封装底层的系统调用,使得文件操作变得更加简单和安全。shutil 模块的功能包括但不限于:

    • 文件和目录的复制、移动、删除等高级操作。
    • 文件和目录的归档和压缩:支持常见的归档和压缩格式,如 ZIP、tar 等。

二、os 模块

分别详细介绍 os 模块中的这些功能,并提供相应的示例代码:

1、文件和目录操作

        当涉及到文件和目录操作时,os 模块提供了一系列函数来执行各种任务,包括创建、删除、重命名等。下面是对 os 模块中文件和目录操作的详细介绍以及相应的示例代码:

使用 os.mkdir() 函数创建单个目录:

import os

os.mkdir("new_directory")

使用 os.makedirs() 函数创建多级目录:

import os

os.makedirs("new_parent_directory/new_child_directory")

使用 os.rename() 函数重命名文件或目录:

import os

os.rename("old_file.txt", "new_file.txt")
os.rename("old_directory", "new_directory")

使用 os.remove() 函数删除文件:

import os

os.remove("file_to_delete.txt")

使用 os.rmdir() 函数删除空目录:

import os

os.rmdir("empty_directory_to_delete")

使用 os.removedirs() 函数递归删除目录:

import os

os.removedirs("directory_to_delete")

使用 os.path.exists() 函数检查文件或目录是否存在:

import os

if os.path.exists("file_or_directory"):
    print("Exists")
else:
    print("Doesn't exist")

使用 os.listdir() 函数获取指定目录中的文件和子目录列表:

import os

files = os.listdir("directory_path")
print("Files in directory:", files)

使用 os.chdir() 函数改变当前工作目录:

import os

os.chdir("/path/to/new_directory")

使用 os.getcwd() 函数获取当前工作目录:

import os

cwd = os.getcwd()
print("Current working directory:", cwd)

使用 os.path.isfile() 函数检查路径是否为文件:

import os

is_file = os.path.isfile("file_path")
print("Is file:", is_file)

使用 os.path.isdir() 函数检查路径是否为目录:

import os

is_directory = os.path.isdir("directory_path")
print("Is directory:", is_directory)

使用 os.path.split() 函数将路径分割为目录和文件名:

import os

directory, filename = os.path.split("path/to/file.txt")
print("Directory:", directory)
print("Filename:", filename)

使用 os.path.join() 函数连接多个路径部分:

import os

path = os.path.join("directory", "file.txt")
print("Joined path:", path)

获取文件大小:

import os

file_path = 'example.txt'

file_size = os.path.getsize(file_path)
print("文件大小 (字节):", file_size)

获取文件创建时间:

import os
import datetime

file_path = 'example.txt'

create_time = os.path.getctime(file_path)
create_time = datetime.datetime.fromtimestamp(create_time)
print("创建时间:", create_time)

获取文件修改时间:

import os
import datetime

file_path = 'example.txt'

modify_time = os.path.getmtime(file_path)
modify_time = datetime.datetime.fromtimestamp(modify_time)
print("修改时间:", modify_time)

获取文件访问时间:

import os
import datetime

file_path = 'example.txt'

access_time = os.path.getatime(file_path)
access_time = datetime.datetime.fromtimestamp(access_time)
print("访问时间:", access_time)

获取文件名:

import os

file_path = 'example.txt'

file_name = os.path.basename(file_path)
print("文件名:", file_name)

获取文件所在目录路径:

import os

file_path = 'example.txt'

directory = os.path.dirname(file_path)
print("文件所在目录:", directory)

获取文件的绝对路径:

import os

file_path = 'example.txt'

absolute_path = os.path.abspath(file_path)
print("文件的绝对路径:", absolute_path)

3、目录遍历

列出目录下的文件和子目录

import os

for item in os.listdir("directory"):
    print(item)

递归遍历目录下的所有文件和子目录

import os

def list_files(directory):
    for root, dirs, files in os.walk(directory):
        for file in files:
            print(os.path.join(root, file))

list_files("directory")

下面是一个示例,展示如何使用递归来遍历目录中的所有文件和子目录:

import os

def list_files(dir_path):
    # 列出目录中的所有文件和子目录
    files = os.listdir(dir_path)
    
    # 遍历文件和子目录
    for file in files:
        # 构造完整的文件路径
        file_path = os.path.join(dir_path, file)
        
        # 如果是文件,则打印文件路径
        if os.path.isfile(file_path):
            print("文件:", file_path)
        # 如果是目录,则递归调用自身遍历子目录
        elif os.path.isdir(file_path):
            print("目录:", file_path)
            list_files(file_path)

# 要遍历的目录路径
directory_path = 'example_directory'

# 调用函数遍历目录
list_files(directory_path)

        在这个示例中,我们首先使用 os.listdir() 函数列出了指定目录中的所有文件和子目录。然后,我们遍历这些文件和子目录,如果是文件,则打印文件路径;如果是目录,则递归调用 list_files() 函数来遍历该子目录。通过这种方式,我们可以遍历目录中的所有文件和子目录,直到所有子目录都被遍历完毕。 

4、环境变量操作

使用 os.environ.get() 方法可以获取指定环境变量的值。如果环境变量不存在,则返回默认值(可选)。

import os

# 获取指定环境变量的值
value = os.environ.get('PATH')

print("PATH 环境变量的值:", value)

使用 os.environ[] 可以设置或修改环境变量的值。

import os

# 设置或修改环境变量的值
os.environ['MY_VARIABLE'] = 'my_value'

使用 del 关键字可以删除指定的环境变量。

import os

# 删除指定的环境变量
del os.environ['MY_VARIABLE']

使用 os.environ 可以列出所有当前的环境变量。

import os

# 列出所有当前的环境变量
for key, value in os.environ.items():
    print(key, "=", value)

6、权限操作

os.chmod(path, mode): 这个函数用于修改文件或目录的权限。path参数是文件或目录的路径,mode参数是一个数字,代表了新的权限设置。你可以使用stat模块中的常量来指定权限,比如stat.S_IRUSR表示用户可读权限。可以使用位操作符将这些常量组合起来形成所需的权限。

import os
import stat

# 设置文件为用户可读写权限
os.chmod("file.txt", stat.S_IRUSR | stat.S_IWUSR)

os.access(path, mode): 这个函数用于检查指定路径的文件或目录是否具有指定的访问权限。mode参数可以是os.F_OK(检查是否存在)、os.R_OK(检查是否可读)、os.W_OK(检查是否可写)和os.X_OK(检查是否可执行)中的一个或多个组合。 

import os

# 检查文件是否可读
if os.access("file.txt", os.R_OK):
    print("File is readable")
else:
    print("File is not readable")

os.umask(mask): 这个函数用于设置新建文件或目录时的默认权限掩码。权限掩码是一个八进制数,用来掩盖新文件或目录的默认权限。

import os

# 设置新建文件或目录的默认权限掩码为022
os.umask(0o022)

os.stat(path): 这个函数返回一个包含文件或目录的状态信息的命名元组。其中包括文件的权限模式,你可以通过位操作和stat模块中的常量来解析这些权限。

import os
import stat

# 获取文件状态信息
file_stat = os.stat("file.txt")

# 解析文件权限模式
mode = file_stat.st_mode
user_readable = bool(mode & stat.S_IRUSR)
user_writable = bool(mode & stat.S_IWUSR)
user_executable = bool(mode & stat.S_IXUSR)

print("User readable:", user_readable)
print("User writable:", user_writable)
print("User executable:", user_executable)

os.chown(path, uid, gid): 这个函数用于修改文件或目录的所有者和所属组。uid参数是新的用户ID,gid参数是新的组ID。

import os

# 将文件的所有者修改为用户ID为1000,组ID为1000的用户和组
os.chown("file.txt", 1000, 1000)

7、系统信息操作

os.name: 这个属性返回当前操作系统的名称。通常情况下,它返回'posix'表示Linux、Unix或Mac OS X系统,返回'nt'表示Windows系统。

import os

print("Current OS:", os.name)

os.getcwd(): 这个函数用于获取当前工作目录的路径。

import os

# 获取当前工作目录
cwd = os.getcwd()
print("Current working directory:", cwd)

os.getlogin(): 这个函数返回当前登录的用户名。但是在某些平台上,它可能返回空字符串或未实现。

import os

# 获取当前登录的用户名
username = os.getlogin()
print("Current login username:", username)

 os.uname(): 这个函数返回包含系统相关信息的元组,比如操作系统的名称、主机名、内核版本等。但是在Windows系统上,它的返回值和Unix系统有所不同。

import os

# 获取系统信息
system_info = os.uname()
print("System info:", system_info)

os.system(command): 这个函数用于执行系统命令。它会调用操作系统的 shell,并执行指定的命令。执行结果会输出到标准输出,返回命令执行状态码。

import os

# 执行系统命令
os.system("ls -l")

 os.cpu_count(): 这个函数返回当前系统的CPU核心数。

import os

# 获取CPU核心数
cpu_count = os.cpu_count()
print("CPU count:", cpu_count)

os.times(): 这个函数返回当前进程的运行时间信息,包括用户CPU时间和系统CPU时间等。

import os

# 获取进程运行时间信息
process_times = os.times()
print("Process times:", process_times)

os.get_terminal_size(): 这个函数返回当前终端的大小,以行数和列数表示。

import os

# 获取终端大小
terminal_size = os.get_terminal_size()
print("Terminal size:", terminal_size)

8、进程管理

os.fork(): 这个函数在Unix/Linux系统上创建一个子进程。在父进程中返回新创建子进程的进程ID,而在子进程中返回0。使用fork()函数,可以在一个进程中创建一个新的子进程,然后在子进程中执行不同的任务。

import os

# 创建子进程
pid = os.fork()

if pid == 0:
    print("Child process")
else:
    print("Parent process")

os.getpid(): 这个函数返回当前进程的进程ID。

import os

# 获取当前进程ID
pid = os.getpid()
print("Current process ID:", pid)

os.getppid(): 这个函数返回当前进程的父进程的进程ID。

import os

# 获取父进程ID
ppid = os.getppid()
print("Parent process ID:", ppid)

os.exec*(): 这一系列函数可以用于执行外部程序,替换当前进程的内容。它们允许你在Python程序中启动其他程序,类似于使用命令行。这些函数包括os.execl()os.execle()os.execlp()os.execlpe()os.execv()os.execve()os.execvp()os.execvpe()

import os

# 执行外部程序
os.execl('/bin/ls', 'ls', '-l')

os.kill(pid, signal): 这个函数用于向指定进程发送信号。pid参数是目标进程的进程ID,signal参数是要发送的信号。

import os
import signal

# 发送信号给进程
os.kill(12345, signal.SIGTERM)

os.wait(): 这个函数用于等待子进程结束,并返回子进程的状态信息。如果没有子进程在运行,它会抛出OSError异常。

import os

# 等待子进程结束
pid, status = os.wait()
print("Child process", pid, "exited with status", status)

三、shutil 模块

    shutil模块是Python标准库中的一个实用工具模块,用于执行文件和目录的高级操作,例如复制、移动、重命名以及删除文件和目录等。它提供了一些函数来简化这些操作,并处理了一些常见的边界情况,比如处理符号链接、处理异常等。下面是shutil模块中一些常用函数的介绍:

shutil.copy(src, dst, *, follow_symlinks=True): 这个函数用于将文件从源路径src复制到目标路径dst。默认情况下,它会跟踪符号链接并复制链接指向的文件。如果follow_symlinks设置为False,则会复制符号链接本身。 

import shutil

# 将文件从源路径复制到目标路径
shutil.copy("source.txt", "destination.txt")

shutil.copy2(src, dst, *, follow_symlinks=True): 这个函数与shutil.copy()类似,但会尽可能地保留文件的元数据(例如权限、时间戳等)。

import shutil

# 将文件从源路径复制到目标路径,并保留元数据
shutil.copy2("source.txt", "destination.txt")

shutil.move(src, dst, copy_function=copy2): 这个函数用于将文件或目录从源路径src移动到目标路径dst。如果dst已经存在,它会覆盖目标文件或目录。copy_function参数指定了在跨不同文件系统移动时用于复制的函数,默认为shutil.copy2()

import shutil

# 将文件或目录从源路径移动到目标路径
shutil.move("source.txt", "destination.txt")

shutil.rmtree(path, ignore_errors=False, onerror=None): 这个函数用于递归地删除指定路径下的所有文件和子目录。如果ignore_errorsTrue,则会忽略错误,继续删除其他文件和目录。

import shutil

# 递归删除目录及其内容
shutil.rmtree("directory_to_delete")

shutil.rmtree(path, ignore_errors=False, onerror=None): 这个函数用于递归地复制整个目录树。

import shutil

# 递归复制目录及其内容
shutil.copytree("source_directory", "destination_directory")

shutil.make_archive(base_name, format, root_dir=None, base_dir=None): 这个函数用于创建归档文件,例如ZIP或tar文件。base_name是归档文件的名称,format指定了归档格式,root_dir是要归档的根目录,base_dir是要包含在归档中的子目录。

import shutil

# 创建ZIP格式的归档文件
shutil.make_archive("archive", "zip", root_dir="source_directory")

shutil.disk_usage(path): 这个函数用于获取指定路径的磁盘使用情况,返回一个命名元组,包含磁盘总大小、已用大小和可用大小。

import shutil

# 获取指定路径的磁盘使用情况
disk_usage = shutil.disk_usage("/")
print("Total:", disk_usage.total)
print("Used:", disk_usage.used)
print("Free:", disk_usage.free)

shutil.get_archive_formats(): 这个函数返回支持的归档格式的列表,每个格式表示为一个元组,包含格式名称和格式描述。

import shutil

# 获取支持的归档格式
archive_formats = shutil.get_archive_formats()
print("Supported archive formats:", archive_formats)

shutil.register_archive_format(name, function[, extra_args[, description]]): 这个函数用于注册自定义的归档格式。name是归档格式的名称,function是创建归档的函数,extra_args是传递给创建函数的额外参数,description是归档格式的描述。

import shutil

# 注册自定义的归档格式
def create_custom_archive(base_name, root_dir):
    pass

shutil.register_archive_format("custom", create_custom_archive, description="Custom archive format")

shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None): 这个函数用于在系统的 PATH 环境变量中查找可执行文件。如果找到了指定的命令,则返回其完整路径,否则返回None

import shutil

# 查找可执行文件的完整路径
path = shutil.which("python")
print("Python executable path:", path)

shutil.get_terminal_size(fallback=(columns, lines)): 这个函数用于获取当前终端的大小,以列数和行数表示。如果无法获取终端大小,则返回一个备用值。

import shutil

# 获取终端大小
terminal_size = shutil.get_terminal_size()
print("Terminal size:", terminal_size)

shutil.samefile(path1, path2): 这个函数用于检查两个路径是否指向同一个文件或目录。如果是同一个文件或目录,则返回True,否则返回False

import shutil

# 检查两个路径是否指向同一个文件或目录
same_file = shutil.samefile("/path/to/file1", "/path/to/file2")
print("Are the paths the same file:", same_file)

<think>嗯,用户想找HAL_TIM_PeriodElapsedCallback函数的定义位置用法。首先,我需要回忆一下STM32的HAL库结构。这个回调函数应该定时器中断相关,对吧?当定时器的周期到了,就会触发这个回调函数。 根据用户提供的引用资料,特别是引用[3],里面提到使用HAL_TIM_Base_Start_IT来启动定时器并开启中断,然后实现中断服务程序中的任务。所以HAL_TIM_PeriodElapsedCallback应该是在用户代码中定义的,用来处理周期性的中断事件。HAL库通常采用回调机制,用户需要自己实现这些回调函数,比如这个函数可能是在定时器更新事件时被调用。 接下来,关于定义的位置,HAL库中的弱定义应该在某个头文件或源文件中,比如stm32xx_hal_tim.h或者对应的.c文件中。用户需要在自己的代码中重新定义这个函数,覆盖弱符号。例如,在main.c或者专门的定时器处理文件中定义。 用法方面,用户需要在初始化定时器并启动中断后,编写这个回调函数的内容,比如翻转LED或者处理数据。同时要注意定时器实例的判断,如果有多个定时器的话,需要用htim的参数来选择正确的定时器。 可能用户遇到的问题是没有正确实现回调函数,或者没有启动中断。需要检查是否调用了正确的启动函数,比如HAL_TIM_Base_Start_IT而不是HAL_TIM_Base_Start,后者可能不会开启中断。 另外,用户可能需要知道如何查找HAL库中的弱定义,这通常是在HAL的源文件中,使用__weak关键字修饰。例如在stm32xx_hal_tim.c中会有这个函数的弱定义,用户在自己的代码中重新实现即可。 还需要提醒用户,中断服务函数的名字可能CubeMX生成的有关,确保中断向量表正确,以及中断优先级设置合理。如果有多个定时器,回调函数中需要通过htim->Instance来判断是哪个定时器触发的,从而执行不同的操作。 总结一下,回答应该包括回调函数的定义位置在用户代码中,需要覆盖HAL的弱定义,用法是在定时器中断发生时执行用户代码,并注意定时器实例的判断。同时提供示例代码常见问题解答,帮助用户正确使用。</think>### HAL_TIM_PeriodElapsedCallback 函数解析 #### 1. 函数定义位置 `HAL_TIM_PeriodElapsedCallback` 是STM32 HAL库中定时器更新事件(周期中断)的**弱定义回调函数**,其默认实现位于HAL库的定时器驱动文件中(例如:`stm32xx_hal_tim.c`),但用户需要在工程中**重新实现该函数**以覆盖默认的弱定义[^3]。 具体来说: - **弱定义位置**:`stm32xx_hal_tim.c`(例如`stm32h7xx_hal_tim.c`) - **用户实现位置**:用户代码中(如`main.c`或自定义的定时器处理文件) #### 2. 函数作用 当定时器的计数器溢出(或达到预设周期值)时,触发更新事件中断,此时`HAL_TIM_PeriodElapsedCallback` 会被调用,用于执行用户自定义的周期性任务,例如:LED闪烁、传感器数据采集等[^3]。 #### 3. 函数原型 ```c __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { // 默认空实现(需用户覆盖) } ``` #### 4. 使用步骤 1. **定时器初始化** 配置定时器参数(预分频系数、计数周期等),例如: ```c TIM_HandleTypeDef htim3; htim3.Instance = TIM3; htim3.Init.Prescaler = 8399; // 84MHz/(8400) = 10kHz htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 9999; // 10kHz/10000 = 1Hz HAL_TIM_Base_Init(&htim3); ``` 2. **启动定时器中断** 使用 `HAL_TIM_Base_Start_IT` 启动定时器并开启中断[^3]: ```c HAL_TIM_Base_Start_IT(&htim3); ``` 3. **实现回调函数** 在用户代码中重新定义函数: ```c void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM3) // 判断触发源 { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // 示例:翻转LED } } ``` #### 5. 注意事项 - 若使用多个定时器,需在回调函数中通过 `htim->Instance` 判断具体触发源[^3]。 - 必须调用 `HAL_TIM_Base_Start_IT`(而非 `HAL_TIM_Base_Start`)以启用中断功能。 - 确保中断服务函数 `TIMx_IRQHandler` 已正确关联到定时器(通常由CubeMX自动生成)。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒秋丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值