YOLOv11-ultralytics-8.3.67部分代码阅读笔记-files.py
files.py
ultralytics\utils\files.py
目录
files.py
1.所需的库和模块
2.class WorkingDirectory(contextlib.ContextDecorator):
3.def spaces_in_path(path):
4.def increment_path(path, exist_ok=False, sep="", mkdir=False):
5.def file_age(path=__file__):
6.def file_date(path=__file__):
7.def file_size(path):
8.def get_latest_run(search_dir="."):
9.def update_models(model_names=("yolo11n.pt",), source_dir=Path("."), update_names=False):
1.所需的库和模块
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/licenseimport contextlib
import glob
import os
import shutil
import tempfile
from contextlib import contextmanager
from datetime import datetime
from pathlib import Path
2.class WorkingDirectory(contextlib.ContextDecorator):
# 这段代码定义了一个名为 WorkingDirectory 的类,它是一个上下文管理器,用于临时更改当前工作目录。这个类继承自 contextlib.ContextDecorator ,这意味着它可以作为上下文管理器( with 语句)使用,也可以作为装饰器使用。
# 定义了一个名为 WorkingDirectory 的类,继承自 contextlib.ContextDecorator 。
# contextlib.ContextDecorator 是一个辅助类,允许上下文管理器同时用作装饰器。这意味着这个类既可以使用 with 语句,也可以用于装饰函数。
class WorkingDirectory(contextlib.ContextDecorator):# 用于临时更改工作目录的上下文管理器和装饰器。# 此类允许使用上下文管理器或装饰器临时更改工作目录。# 它确保在上下文或装饰函数完成后恢复原始工作目录。# 方法:# __enter__:将当前目录更改为指定目录。# __exit__:在退出上下文时恢复原始工作目录。# 示例:# 用作上下文管理器:# >>> with WorkingDirectory('/path/to/new/dir'):# >>> # 在新目录中执行操作# >>> pass# 用作装饰器:# >>> @WorkingDirectory('/path/to/new/dir')# >>> def some_function():# >>> # 在新目录中执行操作# >>> pass"""A context manager and decorator for temporarily changing the working directory.This class allows for the temporary change of the working directory using a context manager or decorator.It ensures that the original working directory is restored after the context or decorated function completes.Attributes:dir (Path): The new directory to switch to.cwd (Path): The original current working directory before the switch.Methods:__enter__: Changes the current directory to the specified directory.__exit__: Restores the original working directory on context exit.Examples:Using as a context manager:>>> with WorkingDirectory('/path/to/new/dir'):>>> # Perform operations in the new directory>>> passUsing as a decorator:>>> @WorkingDirectory('/path/to/new/dir')>>> def some_function():>>> # Perform operations in the new directory>>> pass"""# 定义了类的初始化方法 __init__ ,接受一个参数。# 1.new_dir :要切换到的新目录。def __init__(self, new_dir):# 在实例化时将工作目录设置为‘new_dir’,以便与上下文管理器或装饰器一起使用。"""Sets the working directory to 'new_dir' upon instantiation for use with context managers or decorators."""# 将传入的 new_dir 赋值给实例变量 self.dir ,表示 目标目录 。self.dir = new_dir # new dir# 使用 Path.cwd() 获取当前工作目录,并通过 resolve() 方法解析为绝对路径。# 将 当前工作目录 存储在实例变量 self.cwd 中,用于在上下文退出时恢复。self.cwd = Path.cwd().resolve() # current dir# 定义了 __enter__ 方法,这是上下文管理器进入上下文时调用的方法。def __enter__(self):# 进入上下文后将当前工作目录更改为指定目录。"""Changes the current working directory to the specified directory upon entering the context."""# os.chdir(path)# os.chdir() 函数是 Python 的标准库 os 模块中的一个函数,用于更改当前工作目录。# 参数 :# path :要更改到的目标目录的路径。# 功能描述 :# os.chdir(path) 函数将当前工作目录更改为 path 指定的目录。如果 path 不存在或无法访问,将抛出一个异常。# 异常处理 :# 当尝试更改到一个不存在或无法访问的目录时, os.chdir() 会抛出 FileNotFoundError 或 PermissionError 异常。因此,在实际使用中,可能需要捕获这些异常来处理错误情况。# 使用 os.chdir(self.dir) 切换到目标目录 self.dir 。# 当进入上下文时,当前工作目录会被切换到指定的目录。os.chdir(self.dir)# 定义了 __exit__ 方法,这是上下文管理器退出上下文时调用的方法。 参数 :# 1.exc_type :异常类型(如果有异常发生)。# 2.exc_val :异常值(如果有异常发生)。# 3.exc_tb :异常的回溯信息(如果有异常发生)。# # noqa 是一个注释,通常用于告诉代码检查工具(如 flake8 )忽略这一行的某些检查。def __exit__(self, exc_type, exc_val, exc_tb): # noqa# 退出上下文时恢复原始工作目录。"""Restores the original working directory when exiting the context."""# 在退出上下文时,使用 os.chdir(self.cwd) 将工作目录恢复到进入上下文之前的目录。os.chdir(self.cwd)
# WorkingDirectory 类是一个上下文管理器,用于临时更改当前工作目录。它的主要功能包括。临时切换目录:在进入上下文时切换到指定目录,在退出上下文时恢复到原来的目录。支持 with 语句和装饰器:由于继承自 contextlib.ContextDecorator ,这个类既可以作为上下文管理器使用,也可以作为装饰器使用。
# 使用示例 :
# 作为上下文管理器使用 :
# with WorkingDirectory("/path/to/new/directory"):
# # 在这个代码块中,当前工作目录被切换到 "/path/to/new/directory"
# print("Current directory:", Path.cwd())
# # 退出上下文后,工作目录恢复到原来的目录
# print("Current directory after with block:", Path.cwd())
# 作为装饰器使用 :
# @WorkingDirectory("/path/to/new/directory")
# def my_function():
# # 在这个函数中,当前工作目录被切换到 "/path/to/new/directory"
# print("Current directory in function:", Path.cwd())
# my_function()
# # 函数执行完成后,工作目录恢复到原来的目录
# print("Current directory after function call:", Path.cwd())
# 这种设计使得 WorkingDirectory 类非常灵活,可以在需要临时更改工作目录的场景中方便地使用。
3.def spaces_in_path(path):
# 这段代码定义了一个名为 spaces_in_path 的上下文管理器,用于处理路径中包含空格的情况。它通过临时替换路径中的空格为下划线,避免在某些工具或命令中因空格导致的问题。
# 使用 contextlib.contextmanager 装饰器,将 spaces_in_path 函数定义为一个上下文管理器。这种写法比直接定义类更简洁,适用于简单的上下文管理逻辑。
@contextmanager
# 定义了一个函数 spaces_in_path ,接受一个参数。
# 1.path :需要处理的文件或目录路径。
def spaces_in_path(path):# 上下文管理器处理名称中带有空格的路径。如果路径包含空格,它会用下划线替换它们,将文件/目录复制到新路径,执行上下文代码块,然后将文件/目录复制回其原始位置。# Yields:# (Path):如果存在空格,则用下划线替换临时路径中的空格,否则为原始路径。# 示例:# 使用上下文管理器处理带有空格的路径:# >>> from ultralytics.utils.files import space_in_path# >>> with space_in_path('/path/with space') as new_path:# >>> # 您的代码在这里"""Context manager to handle paths with spaces in their names. If a path contains spaces, it replaces them withunderscores, copies the file/directory to the new path, executes the context code block, then copies thefile/directory back to its original location.Args:path (str | Path): The original path that may contain spaces.Yields:(Path): Temporary path with spaces replaced by underscores if spaces were present, otherwise the original path.Examples:Use the context manager to handle paths with spaces:>>> from ultralytics.utils.files import spaces_in_path>>> with spaces_in_path('/path/with spaces') as new_path:>>> # Your code here"""# If path has spaces, replace them with underscores 如果路径中有空格,则用下划线替换。# 检查路径中是否包含空格。如果路径是 Path 对象或字符串,将其转换为字符串后检查是否包含空格。if " " in str(path):# 检查输入的 path 是否是字符串类型,并将结果存储在变量 string 中。这用于后续决定返回的路径类型(字符串或 Path 对象)。string = isinstance(path, str) # input type# 将输入的路径统一转换为 Path 对象,方便后续操作。path = Path(path)# Create a temporary directory and construct the new path 创建临时目录并构造新路径。# tempfile.TemporaryDirectory()# tempfile.TemporaryDirectory() 是 Python 标准库 tempfile 模块中的一个函数,用于创建一个临时目录。这个临时目录在创建时是空的,并且在使用完毕后可以自动删除。# 函数定义 :# with TemporaryDirectory() as tmp_dir:# print(tmp_dir)# 参数。TemporaryDirectory() 可以接受一些参数来定制临时目录的行为 :# dir :指定一个特定的目录,在该目录下创建临时目录。如果没有指定,则使用系统默认的临时文件目录。# prefix :指定临时目录的前缀。# suffix :指定临时目录的后缀。# ignore_cleanup_errors :一个布尔值,指定是否忽略清理时发生的错误,默认为 False 。# cleanup :一个布尔值,指定是否在退出上下文管理器时清理临时目录,默认为 True 。# mode :设置目录的权限模式,默认为 0o700 。# 在示例中, TemporaryDirectory() 被用作上下文管理器,它创建了一个临时目录,并在 with 块中提供了这个目录的路径。当 with 块执行完毕后,临时目录及其内容将被自动删除。# TemporaryDirectory() 是处理需要临时文件或目录的场合的有用工具,特别是在测试、临时文件处理或任何需要临时存储的场合。使用临时目录可以避免临时文件对主文件系统的污染,并确保资源在使用后被正确清理。# 使用 tempfile.TemporaryDirectory() 创建一个临时目录,用于存放处理后的文件或目录。 tmp_dir 是 临时目录的路径 。with tempfile.TemporaryDirectory() as tmp_dir:# 构造临时路径 tmp_path ,将原始路径的文件名或目录名中的空格替换为下划线。# 例如,如果原始路径是 /path/to/my folder ,则临时路径可能是 /tmp/tempdir/my_folder 。tmp_path = Path(tmp_dir) / path.name.replace(" ", "_")# Copy file/directory 复制文件/目录。# 如果原始路径是一个目录。if path.is_dir():# tmp_path.mkdir(parents=True, exist_ok=True)# shutil.copytree(src, dst, symlinks=False, ignore=None, dirs_exist_ok=False)# shutil.copytree() 是 Python 标准库 shutil (shell utilities)模块中的一个函数,用于递归地复制一个目录到另一个位置。这个函数会复制目录中的所有内容,包括子目录和文件。# 参数 :# src :源目录的路径。# dst :目标目录的路径。如果目标目录已经存在,并且 dirs_exist_ok 参数为 False ,则会抛出一个 FileExistsError 异常。# symlinks :一个布尔值,指定是否复制符号链接。默认为 False ,即不复制符号链接。# ignore :一个可选的回调函数,用于排除不需要复制的文件或目录。# dirs_exist_ok :一个布尔值,指定如果目标目录已经存在,是否允许复制操作继续。默认为 False ,如果目标目录存在,则会抛出异常。# shutil.copytree() 是一个强大的工具,用于复制整个目录树,常用于备份、同步文件或在测试中创建测试数据目录。# 使用 shutil.copytree 将整个目录复制到临时路径。 dirs_exist_ok=True 参数允许目标目录已存在时继续复制。shutil.copytree(path, tmp_path)# 如果原始路径是一个文件。elif path.is_file():# 确保临时路径的父目录存在。tmp_path.parent.mkdir(parents=True, exist_ok=True)# shutil.copy2(src, dst, *, follow_symlinks=True)# shutil.copy2() 是 Python 标准库 shutil (shell utilities)模块中的一个函数,用于复制文件,同时尝试保留原文件的元数据,如修改时间和权限等。# 参数 :# src :源文件的路径。# dst :目标文件的路径。如果目标文件已经存在,将会被覆盖。# follow_symlinks :一个布尔值,默认为 True ,表示是否跟随符号链接。如果设置为 False ,则会复制符号链接本身而不是链接指向的文件。# 功能描述 :# shutil.copy2() 函数将一个文件从 src 路径复制到 dst 路径,并尝试保留源文件的元数据。如果 follow_symlinks 参数为 True ,它将复制符号链接所指向的文件;如果为 False ,则复制符号链接本身。# 异常处理 :# shutil.copy2() 可能会抛出异常,如 FileNotFoundError (源文件不存在)、 PermissionError (没有权限写入目标文件)等。因此,在实际使用中,你可能需要捕获这些异常来处理错误情况:# shutil.copy2() 是一个非常有用的函数,它在复制文件的同时保留了尽可能多的文件属性,这在需要保持文件完整性的场景中非常有用。# shutil.copy2() 是一个方便的工具,用于在需要保留文件元数据的情况下复制文件。与 shutil.copy() 相比, shutil.copy2() 能够更完整地复制文件属性,因此在需要这些属性时应该优先使用 shutil.copy2() 。# 使用 shutil.copy2 将文件复制到临时路径,保留元数据(如修改时间等)。shutil.copy2(path, tmp_path)# 使用 try 块确保在上下文管理器中执行的代码可以正常运行。try:# Yield the temporary path 输出临时路径。# 根据输入路径的类型(字符串或 Path 对象),返回相应的路径。 如果输入是字符串,则返回 临时路径的字符串表示 。 如果输入是 Path 对象,则返回 Path 对象。yield str(tmp_path) if string else tmp_path# 使用 finally 块确保在退出上下文时执行清理操作,无论是否发生异常。finally:# Copy file/directory back 复制文件/目录。# 如果临时路径是一个目录。if tmp_path.is_dir():# 使用 shutil.copytree 将临时目录的内容复制回原始路径,允许覆盖已存在的目录。shutil.copytree(tmp_path, path, dirs_exist_ok=True)# 如果临时路径是一个文件。elif tmp_path.is_file():# 使用 shutil.copy2 将临时文件复制回原始路径,保留元数据。shutil.copy2(tmp_path, path) # Copy back the file 复制回文件。# 如果路径中没有空格。else:# If there are no spaces, just yield the original path 如果没有空格,则直接保留原始路径。# 直接返回原始路径(无需任何处理)。yield path
# spaces_in_path 是一个上下文管理器,用于处理路径中包含空格的情况。它的主要功能包括。临时替换空格:将路径中的空格替换为下划线,避免在某些工具或命令中因空格导致的问题。文件或目录复制:将原始路径的内容复制到临时路径,并在退出上下文时将内容复制回原始路径。类型兼容:根据输入路径的类型(字符串或 Path 对象),返回相应类型的路径。自动清理:在退出上下文时,确保临时目录被清理,原始路径的内容被正确恢复。
# 使用示例 :
# with spaces_in_path("/path/to/my folder") as new_path:
# print("Temporary path:", new_path)
# # 在这个上下文内,可以安全地使用 new_path,它不包含空格
# # 例如,运行某些命令或工具
# # 退出上下文后,原始路径的内容被恢复
# print("Original path restored:", Path("/path/to/my folder").exists())
# 这种上下文管理器非常适用于需要处理路径中空格的场景,例如在调用某些不支持空格路径的命令行工具时。
4.def increment_path(path, exist_ok=False, sep="", mkdir=False):
# 这段代码定义了一个函数 increment_path ,用于处理文件或目录路径的增量命名,避免路径冲突,并且可以选择是否创建目录。
# 定义了一个函数 increment_path ,接受以下参数 :
# 1.path :目标路径(可以是文件或目录)。
# 2.exist_ok :布尔值,默认为 False 。如果为 False ,当路径已存在时,会尝试生成一个增量路径;如果为 True ,则直接返回原路径。
# 3.sep :字符串,默认为空。用于分隔增量编号和原路径。
# 4.mkdir :布尔值,默认为 False 。如果为 True ,会创建路径对应的目录(如果路径是文件,则创建其父目录)。
def increment_path(path, exist_ok=False, sep="", mkdir=False):# 增加文件或目录路径,即 runs/exp --> runs/exp{sep}2、runs/exp{sep}3,... 等等。# 如果路径存在且 `exist_ok` 不为 True,则通过在路径末尾附加数字和 `sep` 来增加路径。如果路径是文件,则将保留文件扩展名。如果路径是目录,则数字将直接附加到路径末尾。如果 `mkdir` 设置为 True,则如果路径尚不存在,则将创建为目录。# 示例:# 增加目录路径:# >>> from pathlib import Path# >>> path = Path("runs/exp")# >>> new_path = increase_path(path)# >>> print(new_path)# runs/exp2# 增加文件路径:# >>> path = Path("runs/exp/results.txt")# >>> new_path = increase_path(path)# >>> print(new_path)# runs/exp/results2.txt"""Increments a file or directory path, i.e., runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc.If the path exists and `exist_ok` is not True, the path will be incremented by appending a number and `sep` tothe end of the path. If the path is a file, the file extension will be preserved. If the path is a directory, thenumber will be appended directly to the end of the path. If `mkdir` is set to True, the path will be created as adirectory if it does not already exist.Args:path (str | pathlib.Path): Path to increment.exist_ok (bool): If True, the path will not be incremented and returned as-is.sep (str): Separator to use between the path and the incrementation number.mkdir (bool): Create a directory if it does not exist.Returns:(pathlib.Path): Incremented path.Examples:Increment a directory path:>>> from pathlib import Path>>> path = Path("runs/exp")>>> new_path = increment_path(path)>>> print(new_path)runs/exp2Increment a file path:>>> path = Path("runs/exp/results.txt")>>> new_path = increment_path(path)>>> print(new_path)runs/exp/results2.txt"""# 将输入的 path 转换为 Path 对象,这是一个跨操作系统的路径处理方式,避免了直接使用字符串拼接路径时可能出现的兼容性问题。path = Path(path) # os-agnostic# 判断路径是否存在且 exist_ok 是否为 False 。如果路径已存在且不允许覆盖( exist_ok=False ),则进入增量路径生成逻辑。if path.exists() and not exist_ok:# 如果路径是一个文件,则将路径的扩展名(后缀)分离出来,以便在增量路径中保留扩展名。 path.with_suffix("") 去掉文件的扩展名, path.suffix 获取扩展名。如果路径是一个目录,则 suffix 设置为空字符串。path, suffix = (path.with_suffix(""), path.suffix) if path.is_file() else (path, "")# Method 1# 从 2 开始循环,尝试生成增量路径,直到找到一个不存在的路径为止。循环范围是 2 到 9999,表示最多尝试生成 9998 个增量路径。for n in range(2, 9999):# 使用格式化字符串生成 增量路径 。 path 是原始路径(去掉扩展名后的部分), sep 是分隔符, n 是增量编号, suffix 是扩展名。p = f"{path}{sep}{n}{suffix}" # increment path# 检查生成的增量路径 p 是否不存在。如果不存在,则跳出循环,表示找到了一个可用的路径。if not os.path.exists(p):break# 将找到的可用增量路径 p 转换为 Path 对象,并赋值给变量 path 。path = Path(p)# 如果参数 mkdir 为 True 。if mkdir:# 则调用 path.mkdir() 创建路径对应的目录。 parents=True 表示如果需要,会创建所有父目录; exist_ok=True 表示如果目录已存在,不会抛出异常。path.mkdir(parents=True, exist_ok=True) # make directory# 返回最终处理后的路径(可能是原始路径、增量路径或已创建的目录路径)。return path
# 这段代码实现了一个路径增量命名的功能,主要用于避免文件或目录命名冲突。它通过在路径后添加编号的方式生成新的路径,并且可以根据需要创建目录。通过参数 exist_ok 和 mkdir ,用户可以灵活控制路径的处理方式。
5.def file_age(path=__file__):
# 这段代码定义了一个函数 file_age ,用于计算指定文件自上次修改以来的天数。
# 定义了一个函数 file_age ,接受一个参数。
# 1.path :默认值为 __file__ (当前脚本文件的路径)。这意味着如果不传入参数,函数将计算当前脚本文件的修改时间。
def file_age(path=__file__):# 返回自上次修改指定文件以来的天数。"""Return days since the last modification of the specified file."""# datetime.datetime.fromtimestamp(timestamp[, tz])# datetime.fromtimestamp() 是 Python 中 datetime 模块的一个方法,用于根据 Unix 时间戳(自1970年1月1日以来的秒数)来创建一个 datetime 对象。# 参数说明 :# timestamp : Unix 时间戳,表示自1970年1月1日(UTC)以来的秒数。# tz (可选): 时区信息。如果提供,方法将返回指定时区对应的 datetime 对象。如果没有提供时区信息,将使用系统本地时区。# 返回值 :# 返回一个 datetime 对象,表示给定 Unix 时间戳对应的日期和时间。# 注意事项 :# datetime.fromtimestamp() 默认返回的是本地时区的时间,如果你需要协调世界时(UTC),可以提供一个时区参数。# 如果你在处理时间戳时需要考虑时区,确保正确地使用 tz 参数。# 在使用 datetime 模块之前,需要先导入该模块。# datetime.fromtimestamp() 是一个非常有用的函数,它允许你将 Unix 时间戳转换为人类可读的日期和时间格式。# 获取文件的最后修改时间。# Path(path).stat().st_mtime :使用 Path 对象的 stat() 方法获取文件的状态信息, st_mtime 是文件的最后修改时间(以时间戳形式表示)。# datetime.fromtimestamp() :将时间戳转换为 datetime 对象。# datetime.now() :获取当前时间的 datetime 对象。# datetime.now() - datetime.fromtimestamp(...) :计算当前时间与文件最后修改时间的差值,结果是一个 timedelta 对象,存储在变量 dt 中。dt = datetime.now() - datetime.fromtimestamp(Path(path).stat().st_mtime) # delta# 返回 timedelta 对象的 days 属性,表示自文件上次修改以来的完整天数。 注释部分 # + dt.seconds / 86400 表示如果需要计算包含小数部分的天数(即包含小时、分钟和秒的部分),可以将 dt.seconds 除以 86400(一天的秒数)并加到 dt.days 上,但这段代码中并未启用。return dt.days # + dt.seconds / 86400 # fractional days
# 这段代码实现了一个简单的功能。计算指定文件自上次修改以来的天数。它通过获取文件的最后修改时间戳,并与当前时间进行比较,最终返回天数差。默认情况下,它计算当前脚本文件的修改时间,但也可以通过传入其他文件路径来计算其他文件的修改时间。
6.def file_date(path=__file__):
# 这段代码定义了一个函数 file_date ,用于获取指定文件的最后修改日期,并将其格式化为 'YYYY-M-D' 格式。
# 定义了一个函数 file_date ,接受一个参数。
# 1.path :默认值为 __file__ (当前脚本文件的路径)。这意味着如果不传入参数,函数将获取当前脚本文件的修改日期。
def file_date(path=__file__):# 以“YYYY-M-D”格式返回文件修改日期。"""Returns the file modification date in 'YYYY-M-D' format."""# 获取文件的最后修改时间。# Path(path).stat().st_mtime :使用 Path 对象的 stat() 方法获取文件的状态信息, st_mtime 是文件的最后修改时间(以时间戳形式表示)。# datetime.fromtimestamp() :将时间戳转换为 datetime 对象,并将其存储在变量 t 中。t = datetime.fromtimestamp(Path(path).stat().st_mtime)# 使用格式化字符串将 datetime 对象 t 的年、月、日部分提取出来,并按照 'YYYY-M-D' 的格式拼接成字符串返回。例如,如果文件的最后修改时间是 2025年2月7日 ,则返回的字符串为 '2025-2-7' 。return f"{t.year}-{t.month}-{t.day}"
# 这段代码实现了一个简单的功能。获取指定文件的最后修改日期,并将其格式化为 'YYYY-M-D' 格式。它通过获取文件的最后修改时间戳,并将其转换为 datetime 对象,最后提取年、月、日并拼接成字符串返回。默认情况下,它获取当前脚本文件的修改日期,但也可以通过传入其他文件路径来获取其他文件的修改日期。
7.def file_size(path):
# 这段代码定义了一个函数 file_size ,用于计算文件或目录的大小,并以兆字节(MB)为单位返回结果。
# 定义了一个函数 file_size ,接受一个参数。
# 1.path :该参数可以是字符串或 Path 对象,表示文件或目录的路径。
def file_size(path):# 以兆字节 (MB) 为单位返回文件或目录的大小。"""Returns the size of a file or directory in megabytes (MB)."""# 检查输入的 path 是否为字符串或 Path 对象。如果不是,函数将直接返回 0.0 。if isinstance(path, (str, Path)):# 定义一个变量 mb ,表示 1 兆字节(MiB)的字节数。 1 << 20 是通过位移操作计算出 1024 ** 2 (即 1048576),这是从字节(bytes)到兆字节(MiB)的换算系数。mb = 1 << 20 # bytes to MiB (1024 ** 2)# 将输入的 path 转换为 Path 对象,以便后续操作。path = Path(path)# 检查 path 是否是一个文件。如果是文件,进入以下逻辑。if path.is_file():# 使用 path.stat().st_size 获取文件的大小(以字节为单位),然后除以 mb (1048576),将结果转换为兆字节(MiB)并返回。return path.stat().st_size / mb# 如果 path 不是一个文件,则检查是否是一个目录。如果是目录,进入以下逻辑。elif path.is_dir():# 使用 path.glob("**/*") 遍历目录及其所有子目录中的所有文件( **/* 表示递归匹配所有文件和目录)。# 使用列表推导式 f.stat().st_size for f in path.glob("**/*") if f.is_file() 获取每个文件的大小(以字节为单位),并使用 sum() 函数计算总大小。# 最后,将总大小除以 mb ,将结果转换为兆字节(MiB)并返回。return sum(f.stat().st_size for f in path.glob("**/*") if f.is_file()) / mb# 如果输入的 path 既不是字符串也不是 Path 对象,或者路径无效(既不是文件也不是目录),则返回 0.0 。return 0.0
# 这段代码实现了一个功能。计算文件或目录的大小,并以兆字节(MB)为单位返回结果。它通过以下逻辑实现。检查输入路径是否有效(字符串或 Path 对象)。如果路径是文件,直接获取文件大小并转换为 MB。如果路径是目录,递归遍历目录中的所有文件,计算总大小并转换为 MB。如果路径无效或既不是文件也不是目录,返回 0.0 。这种实现方式既支持单个文件的大小计算,也支持整个目录的大小计算,具有较高的通用性。
8.def get_latest_run(search_dir="."):
# 这段代码定义了一个函数 get_latest_run ,用于在指定目录中查找最新的 last.pt 文件,通常用于恢复训练模型。
# 定义了一个函数 get_latest_run ,接受一个参数。
# 1.search_dir :默认值为 "." ,表示当前工作目录。该参数指定了要搜索的目录。
def get_latest_run(search_dir="."):# 返回指定目录中最新的“last.pt”文件的路径,以恢复训练。"""Returns the path to the most recent 'last.pt' file in the specified directory for resuming training."""# 使用 glob.glob 函数搜索指定目录及其所有子目录( recursive=True )中所有匹配 last*.pt 的文件路径。# search_dir 是搜索的根目录。# /**/last*.pt 是搜索模式,表示在所有子目录中查找以 last 开头且以 .pt 结尾的文件。# 结果存储在变量 last_list 中,它是一个 包含所有匹配文件路径的列表 。last_list = glob.glob(f"{search_dir}/**/last*.pt", recursive=True)# 如果 last_list 不为空(即找到了匹配的文件),使用 max 函数找到其中“最新”的文件。# key=os.path.getctime :指定 max 函数的比较标准为文件的创建时间( getctime )。# max(last_list, key=os.path.getctime) :返回列表中创建时间最新的文件路径。# 如果 last_list 为空(即没有找到匹配的文件),返回空字符串 "" 。return max(last_list, key=os.path.getctime) if last_list else ""
# 这段代码实现了一个功能。在指定目录及其子目录中查找最新的 last.pt 文件,通常用于恢复训练模型。它通过以下逻辑实现。使用 glob.glob 在指定目录及其子目录中搜索所有匹配 last*.pt 的文件。如果找到文件,通过文件的创建时间找到最新的文件。如果没有找到文件,返回空字符串。这种实现方式简单高效,适用于需要恢复训练模型的场景,例如在深度学习项目中。
9.def update_models(model_names=("yolo11n.pt",), source_dir=Path("."), update_names=False):
# 这段代码定义了一个函数 update_models ,用于更新指定模型文件,并将其保存到目标目录中。
# 定义了一个函数 update_models ,接受以下参数 :
# 1.model_names :一个元组,默认值为 ("yolo11n.pt",) ,包含需要更新的模型文件名。
# 2.source_dir :一个 Path 对象,默认值为当前目录( Path(".") ),表示模型文件所在的源目录。
# 3.update_names :一个布尔值,默认值为 False ,表示是否更新模型的类别名称。
def update_models(model_names=("yolo11n.pt",), source_dir=Path("."), update_names=False):# 更新并重新保存“updated_models”子目录中的指定 YOLO 模型。"""Updates and re-saves specified YOLO models in an 'updated_models' subdirectory.Args:model_names (Tuple[str, ...]): Model filenames to update.source_dir (Path): Directory containing models and target subdirectory.update_names (bool): Update model names from a data YAML.Examples:Update specified YOLO models and save them in 'updated_models' subdirectory:>>> from ultralytics.utils.files import update_models>>> model_names = ("yolo11n.pt", "yolov8s.pt")>>> update_models(model_names, source_dir=Path("/models"), update_names=True)"""# 导入了 YOLO 类和 default_class_names 函数,这些是用于加载和更新模型的工具。from ultralytics import YOLOfrom ultralytics.nn.autobackend import default_class_names# 定义目标目录路径,位于 source_dir 下的 updated_models 文件夹。target_dir = source_dir / "updated_models"# 使用 mkdir 方法创建目标目录, parents=True 表示如果需要,会创建所有父目录; exist_ok=True 表示如果目录已存在,不会抛出异常。target_dir.mkdir(parents=True, exist_ok=True) # Ensure target directory exists# 遍历 model_names 中的每个模型文件名。for model_name in model_names:# 构造模型文件的完整路径,位于 source_dir 下。model_path = source_dir / model_name# 打印正在加载的模型路径,用于提示用户。print(f"Loading model from {model_path}") # 从 {model_path} 加载模型。# Load model# 使用 YOLO 类加载模型文件。model = YOLO(model_path)# 将模型转换为半精度(16位浮点数)格式,通常用于加速推理并减少模型大小。model.half()# 如果 update_names 为 True 。if update_names: # update model names from a dataset YAML# 则更新模型的类别名称。这里使用 default_class_names("coco8.yaml") 从 coco8.yaml 文件中获取类别名称,并将其赋值给模型的 names 属性。# def default_class_names(data=None):# -> 用于从输入的 YAML 文件中提取类别名称,或者在无法提取时返回默认的类别名称。提取 names 字段,返回类别名称列表。如果无法从输入数据中提取类别名称(或未提供输入),则返回默认的类别名称字典。# -> return yaml_load(check_yaml(data))["names"] / return {i: f"class{i}" for i in range(999)} # return default if above errorsmodel.model.names = default_class_names("coco8.yaml")# Define new save path# 定义 保存更新后模型的目标路径 ,位于 target_dir 下。save_path = target_dir / model_name# Save model using model.save()# 打印正在保存的模型路径,用于提示用户。print(f"Re-saving {model_name} model to {save_path}") # 将 {model_name} 模型重新保存至 {save_path}。# 使用 model.save() 方法将更新后的模型保存到目标路径。model.save(save_path)
# 这段代码实现了一个功能。更新指定的 YOLO 模型文件,并将其保存到目标目录中。它通过以下逻辑实现。创建目标目录,用于存放更新后的模型。遍历指定的模型文件名,加载每个模型。将模型转换为半精度格式。如果需要,更新模型的类别名称。将更新后的模型保存到目标目录。这种实现方式适用于需要批量更新模型文件的场景,例如在深度学习项目中对模型进行优化或更新类别名称。
相关文章:
YOLOv11-ultralytics-8.3.67部分代码阅读笔记-files.py
files.py ultralytics\utils\files.py 目录 files.py 1.所需的库和模块 2.class WorkingDirectory(contextlib.ContextDecorator): 3.def spaces_in_path(path): 4.def increment_path(path, exist_okFalse, sep"", mkdirFalse): 5.def file_age(path__fi…...

微信小程序案例1——制作猫眼电影底部标签导航栏
文章目录 一、项目步骤1 新建一个无AppID的movie项目2将准备好的底部标签导航图标拷贝到movie项目下面(将图标文件夹image放到项目文件夹里)3 打开App.json配置文件,在pages数组里添加4个页面路径:电影“pages/movie/movie”、影院“pages/cinema/cinema…...

【大数据技术】搭建完全分布式高可用大数据集群(Kafka)
搭建完全分布式高可用大数据集群(Kafka) kafka_2.13-3.9.0.tgz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群 Kafka 的详细步骤。 注意: 统一约定将软件安装包存放于虚拟机的/software目录下,软件安装至/opt目录下。 安…...
【服务器知识】如何在linux系统上搭建一个nfs
文章目录 NFS网络系统搭建**1. 准备工作****2. 服务器端配置****(1) 安装 NFS 服务****(2) 创建共享目录****(3) 配置共享规则****(4) 生效配置并启动服务****(5) 防火墙配置** **3. 客户端配置****(1) 安装 NFS 客户端工具****(2) 创建本地挂载点****(3) 挂载 NFS 共享目录***…...

图片画质增强:轻松提升画质
前言: 今天给大家推荐一款非常实用的图片画质增强软件,它无需联网即可使用,完全离线操作,这款软件基于先进的深度学习技术,能够对模糊图片进行强大的高清处理,效果令人惊艳。 图片画质增强:一…...

vscode快速接入deepseek 实践操作
背景说明 在deepseek快速火爆的情况下,也想自己体验一把。看看在vscode中集成进来,方便平时的脚本开发。对于年纪大的人还是非常方便的。 操作过程 安装continue 打开vscode进入扩展市场,搜索安装 安装完成就是上面的样子,会…...

mapbox进阶,添加绘图扩展插件,绘制圆形
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️MapboxDraw 绘图控件二、🍀添加绘图扩…...
Cursor 与多语言开发:全栈开发的利器
引言 全栈开发要求开发者跨越前端、后端、数据库甚至数据科学等多个技术领域,而不同技术栈往往需要切换工具和思维方式。Cursor 作为一款 AI 驱动的智能编程助手,凭借其对 20 编程语言 和主流框架的深度支持,正在成为全栈开发的“瑞士军刀”…...

2025 CCF BDCI|“基于TPU平台的OCR模型性能优化”一等奖作品
2024年12月,中国计算机学会在海南博鳌成功举办了第十二届CCF大数据与计算智能大赛(简称2024 CCF BDCI)。本届比赛的算能赛道吸引了1748名选手报名,经过激烈角逐,北京航空航天大学的“常务副SOTA”团队脱颖而出…...

FPGA的IP核接口引脚含义-快解
疑问 手册繁琐,怎样快速了解IP核各输入输出接口引脚的含义。 答疑 不慌不慌,手册确实比较详细但繁琐,如何快速知晓该部分信息,涛tao道长给你们说,简单得很,一般新入门的道友有所不知,往往后面…...

数据库高安全—审计追踪:传统审计统一审计
书接上文数据库高安全—角色权限:权限管理&权限检查,从权限管理和权限检查方面解读了高斯数据库的角色权限,本篇将从传统审计和统一审计两方面对高斯数据库的审计追踪技术进行解读。 4 审计追踪 4.1 传统审计 审计内容的记录方式通…...

机器学习 - 需要了解的条件概率、高斯分布、似然函数
似然函数是连接数据与参数的桥梁,通过“数据反推参数”的逆向思维,成为统计推断的核心工具。理解它的关键在于区分“参数固定时数据的概率”与“数据固定时参数的合理性”,这种视角转换是掌握现代统计学和机器学习的基础。 一、在学习似然函…...

Spring Boot Web 入门
目录 Spring Boot Web 是 Spring Boot 框架的一个重要模块,它简化了基于 Spring 的 Web 应用程序的开发过程。以下是一个 Spring Boot Web 项目的入门指南,涵盖了项目创建、代码编写、运行等关键步骤。 1. 项目创建 使用 Spring Initializr 使用 IDE …...

神经网络|(八)概率论基础知识-二项分布及python仿真
【1】引言 前序已经学习了古典概型、条件概率、全概率公式和贝叶斯公式,它们作为基础,解释了事件发生及其概率的对应关系,相关文章链接为: 神经网络|(四)概率论基础知识-古典概型-CSDN博客 神经网络|(五)概率论基础知识-条件概…...
【面试场景】MySQL分布式主键选取
文章目录 一. MySQL的自增主键二. UUID三. 雪花ID(推荐) 我的博客地址 一. MySQL的自增主键 适合单表的情况, 在分布式分库分表下可能会有一些问题 主键冲突问题 在分布式系统中,多个数据库节点独立生成自增主键,很容易出现重复的主键值。例如ÿ…...
执行git stash drop stash@{x} 时出现error: unknown switch `e‘ 的解决方式
原因: 在 PowerShell 或某些 Shell 中,{} 是特殊符号,stash{0} 会被解析成 stash 0,而 后的字符可能被误认为选项(如 -e),使 Git 收到意外的 -e 参数,导致报错 unknown switch ‘e’。 解决方…...

链表和 list
一、单链表的模拟实现 1.实现方式 链表的实现方式分为动态实现和静态实现两种。 动态实现是通过 new 申请结点,然后通过 delete 释放结点的形式构造链表。这种实现方式最能体 现链表的特性; 静态实现是利用两个数组配合来模拟链表。一个表示数据域&am…...
windows 蓝牙驱动开发-传输总线驱动程序常见问题
以下是驱动程序开发人员在开发总线驱动程序以支持蓝牙功能时可能会遇到的一些常见问题和方案。 我的串行总线驱动程序遇到了一些错误。 它意味着什么? 代码 10-49:设备管理器生成的错误代码。 代码 51:当串行总线驱动程序具有相关的控制器…...

Qt修仙之路2-1 炼丹初成
widget.cpp #include "widget.h" #include<QDebug> //实现槽函数 void Widget::login1() {QString userusername_input->text();QString passpassword_input->text();//如果不勾选无法登入if(!check->isChecked()){qDebug()<<"xxx"&…...

【含开题报告+文档+PPT+源码】基于SpringBoot+Vue宠物预约上门服务预约平台
开题报告 本研究论文旨在构建并阐述一个基于 SpringBoot 和 Vue 技术栈开发的宠物上门服务预约平台的设计与实现。该平台集成了丰富的功能模块,为用户提供一体化的便捷服务体验。首先,用户能够通过注册并登录系统,享受个性化的服务流程。在平…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...

边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...