66 lines
2.4 KiB
Python
66 lines
2.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Sun Dec 31 17:07:09 2023
|
|
|
|
@author: ym
|
|
"""
|
|
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
import re
|
|
import yaml
|
|
|
|
class IterableSimpleNamespace(SimpleNamespace):
|
|
"""
|
|
Ultralytics IterableSimpleNamespace is an extension class of SimpleNamespace that adds iterable functionality and
|
|
enables usage with dict() and for loops.
|
|
"""
|
|
|
|
def __iter__(self):
|
|
"""Return an iterator of key-value pairs from the namespace's attributes."""
|
|
return iter(vars(self).items())
|
|
|
|
def __str__(self):
|
|
"""Return a human-readable string representation of the object."""
|
|
return '\n'.join(f'{k}={v}' for k, v in vars(self).items())
|
|
|
|
def __getattr__(self, attr):
|
|
"""Custom attribute access error message with helpful information."""
|
|
name = self.__class__.__name__
|
|
raise AttributeError(f"""
|
|
'{name}' object has no attribute '{attr}'. This may be caused by a modified or out of date ultralytics
|
|
'default.yaml' file.\nPlease update your code with 'pip install -U ultralytics' and if necessary replace
|
|
DEFAULT_CFG_PATH with the latest version from
|
|
https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/default.yaml
|
|
""")
|
|
|
|
def get(self, key, default=None):
|
|
"""Return the value of the specified key if it exists; otherwise, return the default value."""
|
|
return getattr(self, key, default)
|
|
|
|
|
|
|
|
def yaml_load(file='data.yaml', append_filename=False):
|
|
"""
|
|
Load YAML data from a file.
|
|
|
|
Args:
|
|
file (str, optional): File name. Default is 'data.yaml'.
|
|
append_filename (bool): Add the YAML filename to the YAML dictionary. Default is False.
|
|
|
|
Returns:
|
|
(dict): YAML data and file name.
|
|
"""
|
|
assert Path(file).suffix in ('.yaml', '.yml'), f'Attempting to load non-YAML file {file} with yaml_load()'
|
|
with open(file, errors='ignore', encoding='utf-8') as f:
|
|
s = f.read() # string
|
|
|
|
# Remove special characters
|
|
if not s.isprintable():
|
|
s = re.sub(r'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD\U00010000-\U0010ffff]+', '', s)
|
|
|
|
# Add YAML filename to dict and return
|
|
data = yaml.safe_load(s) or {} # always return a dict (yaml.safe_load() may return None for empty files)
|
|
if append_filename:
|
|
data['yaml_file'] = str(file)
|
|
return data |