config.basic.core ================= .. py:module:: config.basic.core .. autoapi-nested-parse:: 主要中间层 .. versionadded:: 0.2.0 Classes ------- .. autoapisummary:: config.basic.core.BasicConfigData config.basic.core.BasicConfigPool config.basic.core.BasicIndexedConfigData config.basic.core.BasicSingleConfigData config.basic.core.ConfigFile config.basic.core.PHelper Module Contents --------------- .. py:class:: BasicConfigData Bases: :py:obj:`config.abc.ABCConfigData`, :py:obj:`abc.ABC` 配置数据基类 .. versionadded:: 0.1.5 .. versionchanged:: 0.2.0 重命名 ``BaseConfigData`` 为 ``BasicConfigData`` .. py:method:: __format__(format_spec: str) -> str .. py:method:: freeze(freeze: bool | None = None) -> Self 冻结配置数据 (切换只读模式) :param freeze: 是否冻结配置数据, 为 :py:const:`None` 时进行切换 :type freeze: bool | None :return: 返回当前实例便于链式调用 :rtype: Self .. versionadded:: 0.1.5 .. py:method:: from_data(*args: Any, **kwargs: Any) -> Self :classmethod: 提供创建同类型配置数据的快捷方式 :return: 新的配置数据 :rtype: Self .. note:: 套壳 ``__init__`` 主要是为了方便内部快速创建与传入的ABCConfigData同类型的对象 例如: .. code-block:: python type(instance)(data) 可以简写为 .. code-block:: python instance.from_data(data) .. versionchanged:: 0.2.0 现在会自适应初始化参数 .. py:attribute:: __slots__ :value: () .. py:attribute:: _read_only :type: bool | None :value: False .. py:property:: data_read_only :type: bool | None 配置数据是否为只读 :return: 配置数据是否为只读 :rtype: bool | None .. versionadded:: 0.1.3 .. versionchanged:: 0.1.5 改为抽象属性 .. py:property:: read_only :type: bool | None 配置数据是否为 ``只读模式`` :return: 配置数据是否为 ``只读模式`` :rtype: bool | None .. py:class:: BasicConfigPool(root_path: str = './.config') Bases: :py:obj:`config.abc.ABCConfigPool`, :py:obj:`abc.ABC` 基础配置池类 实现了一些通用方法 .. versionchanged:: 0.2.0 重命名 ``BaseConfigPool`` 为 ``BasicConfigPool`` :param root_path: 配置根路径 :type root_path: str .. py:method:: __contains__(item: Any) -> bool .. versionadded:: 0.1.2 .. py:method:: __getitem__(item: str | tuple[str, str]) -> dict[str, config.abc.ABCConfigFile[Any]] | config.abc.ABCConfigFile[Any] .. py:method:: __len__() -> int 配置文件总数 .. py:method:: __repr__() -> str .. py:method:: _get_formats(file_name: str, config_formats: str | collections.abc.Iterable[str] | None, configfile_format: str | None = None) -> collections.abc.Iterable[str] 从给定参数计算所有可能的配置格式 .. attention:: 返回所有可能的配置格式,不会检查配置格式是否存在! 可迭代对象的产生顺序即为配置格式优先级,优先级逻辑见下表 :param file_name: 文件名 :type file_name: str :param config_formats: 配置格式 :type config_formats: str | Iterable[str] | None :param configfile_format: 该配置文件对象本身配置格式属性的值 可选项,一般在保存时填入 用于在没手动指定配置格式且没文件后缀时使用该值进行尝试 .. seealso:: :py:attr:`ABCConfigFile.config_format` :return: 配置格式 :rtype: Iterable[str] :raise UnsupportedConfigFormatError: 不支持的配置格式 格式计算优先级 -------------- 1.config_formats的bool求值为真 2.文件名注册了对应的SL处理器 3.configfile_format非None .. versionadded:: 0.2.0 .. py:method:: _try_sl_processors(namespace: str, file_name: str, config_formats: str | collections.abc.Iterable[str] | None, processor: collections.abc.Callable[[Self, str, str, str], BasicConfigPool._try_sl_processors.R], file_config_format: str | None = None) -> BasicConfigPool._try_sl_processors.R 自动尝试推断ABCConfigFile所支持的config_format :param namespace: 命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str :param config_formats: 配置格式 :type config_formats: str | Iterable[str] | None :param processor: 处理器,参数为[配置池对象, 命名空间, 文件名, 配置格式]返回值会被直接返回, 出现意料内的SL处理器无法处理需抛出FailedProcessConfigFileError以允许继续尝试别的SL处理器 :type processor: Callable[[Self, str, str, str], R] :param file_config_format: 该配置文件对象本身配置格式属性的值 可选项,一般在保存时填入 用于在没手动指定配置格式且没文件后缀时使用该值进行尝试 .. seealso:: :py:attr:`ABCConfigFile.config_format` :return: 处理器返回值 :rtype: R :raise UnsupportedConfigFormatError: 不支持的配置格式 :raise FailedProcessConfigFileError: 处理配置文件失败 .. seealso:: 格式计算优先级 :py:meth:`_get_formats` .. versionadded:: 0.1.2 .. versionchanged:: 0.2.0 拆分格式计算到方法 :py:meth:`_get_formats` .. py:method:: discard(namespace: str, file_name: str | None = None) -> Self 确保配置文件不存在于配置池 :param namespace: 命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str | None :return: 返回当前实例便于链式调用 :rtype: Self .. versionadded:: 0.2.0 .. py:method:: get(namespace: str) -> dict[str, config.abc.ABCConfigFile[Any]] | None get(namespace: str, file_name: str) -> config.abc.ABCConfigFile[Any] | None get(namespace: str, file_name: str | None = None) -> dict[str, config.abc.ABCConfigFile[Any]] | config.abc.ABCConfigFile[Any] | None 获取配置 如果配置不存在则返回None :param namespace: 命名空间 :type namespace: str :param file_name: 文件名 :type file_name: Optional[str] :return: 配置 :rtype: dict[str, ABCConfigFile] | ABCConfigFile | None .. py:method:: initialize(namespace: str, file_name: str, *args: Any, config_formats: str | collections.abc.Iterable[str] | None = None, **kwargs: Any) -> config.abc.ABCConfigFile[Any] 初始化配置文件到指定命名空间并返回 :param namespace: 命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str :param config_formats: 配置格式 :type config_formats: str | Iterable[str] | None :return: 配置对象 :rtype: ABCConfigFile .. versionadded:: 0.2.0 .. py:method:: load(namespace: str, file_name: str, *args: Any, config_formats: str | collections.abc.Iterable[str] | None = None, allow_initialize: bool = False, **kwargs: Any) -> config.abc.ABCConfigFile[Any] 加载配置到指定命名空间并返回 :param namespace: 命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str :param config_formats: 配置格式 :type config_formats: str | Iterable[str] | None :param allow_initialize: 是否允许初始化配置文件 :type allow_initialize: bool :return: 配置对象 :rtype: ABCConfigFile .. versionchanged:: 0.2.0 现在会像 :py:meth:`save` 一样接收并传递额外参数 删除参数 ``config_file_cls`` 重命名参数 ``allow_create`` 为 ``allow_initialize`` 现在由 :py:meth:`ABCConfigFile.initialize` 创建新的空 :py:class:`ABCConfigFile` 对象 .. py:method:: remove(namespace: str, file_name: str | None = None) -> Self 从配置池移除配置文件 :param namespace: 命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str | None :return: 返回当前实例便于链式调用 :rtype: Self .. versionchanged:: 0.2.0 返回当前实例便于链式调用 重命名 ``delete`` 为 ``remove`` .. py:method:: save(namespace: str, file_name: str, config_formats: str | collections.abc.Iterable[str] | None = None, config: config.abc.ABCConfigFile[Any] | None = None, *args: Any, **kwargs: Any) -> Self 保存配置 :param namespace: 命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str :param config_formats: 配置格式 :type config_formats: str | Iterable[str] | None :param config: 配置文件,可选,提供此参数相当于自动调用了一遍pool.set :type config: ABCConfigFile | None :return: 返回当前实例便于链式调用 :rtype: Self .. versionchanged:: 0.1.2 添加参数 ``config_formats`` 添加参数 ``config`` .. versionchanged:: 0.2.0 返回当前实例便于链式调用 .. py:method:: save_all(*, ignore_err: bool = False) -> dict[str, dict[str, tuple[config.abc.ABCConfigFile[Any], Exception]]] | None 保存所有配置 :param ignore_err: 是否忽略保存导致的错误 :type ignore_err: bool :return: ignore_err为True时返回{Namespace: {FileName: (ConfigObj, Exception)}},否则返回None :rtype: dict[str, dict[str, tuple[ABCConfigFile, Exception]]] | None .. versionchanged:: 0.3.0 更改参数 ``ignore_err`` 为仅关键字参数 .. py:method:: set(namespace: str, file_name: str, config: config.abc.ABCConfigFile[Any]) -> Self 设置配置 :param namespace: 命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str :param config: 配置 :type config: ABCConfigFile :return: 返回当前实例便于链式调用 :rtype: Self .. versionchanged:: 0.2.0 返回当前实例便于链式调用 .. py:attribute:: FileNameProcessors :type: collections.OrderedDict[str | re.Pattern[str], list[str]] 文件名处理器注册表 .. caution:: 此字典是顺序敏感的,越靠前越优先被检查 数据结构: ``{文件名匹配: [处理器注册名]}`` 文件名匹配: - 为字符串时会使用 ``endswith`` 进行匹配 - 为 ``re.Pattern`` 时会使用 ``Pattern.fullmatch`` 进行匹配 .. versionchanged:: 0.2.0 重命名 ``FileExtProcessor`` 为 ``FileNameProcessors`` 现在是顺序敏感的 .. py:attribute:: SLProcessors :type: dict[str, ABCConfigSL] 处理器注册表 数据结构: ``{处理器注册名: 处理器实例}}`` .. versionchanged:: 0.2.0 重命名 ``SLProcessor`` 为 ``SLProcessors`` .. py:attribute:: __slots__ :value: () .. py:attribute:: _configs :type: dict[str, dict[str, config.abc.ABCConfigFile[Any]]] .. py:attribute:: _helper .. py:attribute:: _root_path :value: './.config' .. py:property:: configs :type: dict[str, dict[str, config.abc.ABCConfigFile[Any]]] 配置文件字典 .. py:property:: helper :type: config.abc.ABCProcessorHelper 处理器助手 .. py:property:: root_path :type: str 配置文件根目录 .. py:class:: BasicIndexedConfigData(data: D) Bases: :py:obj:`BasicSingleConfigData`\ [\ :py:obj:`BasicIndexedConfigData.D`\ ], :py:obj:`config.abc.ABCIndexedConfigData`\ [\ :py:obj:`BasicIndexedConfigData.D`\ ], :py:obj:`abc.ABC` 支持 ``索引`` 操作的配置数据基类 .. versionadded:: 0.1.5 .. versionchanged:: 0.2.0 重命名 ``BaseSupportsIndexConfigData`` 为 ``BasicIndexedConfigData`` :param data: 配置的原始数据 :type data: Any .. py:method:: __bool__() -> bool .. py:method:: __contains__(key: Any) -> bool .. py:method:: __deepcopy__(memo: dict[str, Any]) -> Self .. py:method:: __delitem__(index: Any) -> None .. py:method:: __eq__(other: Any) -> bool .. py:method:: __format__(format_spec: str) -> str .. py:method:: __getitem__(index: Any) -> Any .. py:method:: __iter__() -> collections.abc.Iterator[D] .. py:method:: __len__() -> int .. py:method:: __repr__() -> str .. py:method:: __setitem__(index: Any, value: Any) -> None .. py:method:: __str__() -> str .. py:method:: _process_path(path: config.abc.ABCPath[Any], path_checker: collections.abc.Callable[[Any, config.abc.AnyKey, config.abc.ABCPath[Any], int], BasicIndexedConfigData._process_path.X], process_return: collections.abc.Callable[[Any], BasicIndexedConfigData._process_path.Y]) -> BasicIndexedConfigData._process_path.X | BasicIndexedConfigData._process_path.Y 处理键路径的通用函数 :param path: 键路径 :type path: ABCPath :param path_checker: 检查并处理每个路径段,返回值非None时结束操作并返回值 :type path_checker: Callable[(current_data: Any, current_key: ABCKey, last_path: ABCPath, path_index: int), X] :param process_return: 处理最终结果,该函数返回值会被直接返回 :type process_return: Callable[(current_data: Any), Y] :return: 处理结果 :rtype: X | Y .. versionchanged:: 0.2.0 重命名参数 ``process_check`` 为 ``path_checker`` .. py:method:: delete(path: config.abc.PathLike) -> Self 删除路径 :param path: 路径 :type path: PathLike :return: 返回当前实例便于链式调用 :rtype: Self :raise ConfigDataReadOnlyError: 配置数据为只读 :raise ConfigDataTypeError: 配置数据类型错误 :raise RequiredPathNotFoundError: 需求的键不存在 .. py:method:: exists(path: config.abc.PathLike, *, ignore_wrong_type: bool = False) -> bool 判断路径是否存在 :param path: 路径 :type path: PathLike :param ignore_wrong_type: 忽略配置数据类型错误 :type ignore_wrong_type: bool :return: 路径是否存在 :rtype: bool :raise ConfigDataTypeError: 配置数据类型错误 .. py:method:: freeze(freeze: bool | None = None) -> Self 冻结配置数据 (切换只读模式) :param freeze: 是否冻结配置数据, 为 :py:const:`None` 时进行切换 :type freeze: bool | None :return: 返回当前实例便于链式调用 :rtype: Self .. versionadded:: 0.1.5 .. py:method:: from_data(*args: Any, **kwargs: Any) -> Self :classmethod: 提供创建同类型配置数据的快捷方式 :return: 新的配置数据 :rtype: Self .. note:: 套壳 ``__init__`` 主要是为了方便内部快速创建与传入的ABCConfigData同类型的对象 例如: .. code-block:: python type(instance)(data) 可以简写为 .. code-block:: python instance.from_data(data) .. versionchanged:: 0.2.0 现在会自适应初始化参数 .. py:method:: get(path: config.abc.PathLike, default: BasicIndexedConfigData.get.V | None = None, *, return_raw_value: bool = False) -> BasicIndexedConfigData.get.V | Any 获取路径的值的*快照*,路径不存在时填充默认值 :param path: 路径 :type path: PathLike :param default: 默认值 :type default: V :param return_raw_value: 是否获取原始值 :type return_raw_value: bool :return: 路径的值 :rtype: V | Any :raise ConfigDataTypeError: 配置数据类型错误 例子 ---- >>> from c41811.config import MappingConfigData >>> data = MappingConfigData({"key": "value"}) 路径存在时返回值 >>> data.get("key") 'value' 路径不存在时返回默认值None >>> print(data.get("not exists")) None 自定义默认值 >>> data.get("with default", default="default value") 'default value' .. versionchanged:: 0.2.0 重命名参数 ``get_raw`` 为 ``return_raw_value`` .. py:method:: modify(path: config.abc.PathLike, value: Any, *, allow_create: bool = True) -> Self 修改路径的值 :param path: 路径 :type path: PathLike :param value: 值 :type value: Any :param allow_create: 是否允许创建不存在的路径,默认为True :type allow_create: bool :return: 返回当前实例便于链式调用 :rtype: Self :raise ConfigDataReadOnlyError: 配置数据为只读 :raise ConfigDataTypeError: 配置数据类型错误 :raise RequiredPathNotFoundError: 需求的键不存在 .. caution:: ``value`` 参数未默认做深拷贝,可能导致非预期行为 .. attention:: ``allow_create`` 时,使用与 `self.data` 一样的类型新建路径 .. py:method:: retrieve(path: config.abc.PathLike, *, return_raw_value: bool = False) -> Any 获取路径的值的*快照* :param path: 路径 :type path: PathLike :param return_raw_value: 是否获取原始值,为 :py:const:`False` 时,会将Mapping | Sequence转换为对应类 :type return_raw_value: bool :return: 路径的值 :rtype: Any :raise ConfigDataTypeError: 配置数据类型错误 :raise RequiredPathNotFoundError: 需求的键不存在 .. versionchanged:: 0.2.0 重命名参数 ``get_raw`` 为 ``return_raw_value`` .. py:method:: setdefault(path: config.abc.PathLike, default: BasicIndexedConfigData.setdefault.V | None = None, *, return_raw_value: bool = False) -> BasicIndexedConfigData.setdefault.V | Any 如果路径不在配置数据中则填充默认值到配置数据并返回 :param path: 路径 :type path: PathLike :param default: 默认值 :type default: V :param return_raw_value: 是否获取原始值 :type return_raw_value: bool :return: 路径的值 :rtype: V | Any :raise ConfigDataReadOnlyError: 配置数据为只读 :raise ConfigDataTypeError: 配置数据类型错误 例子 ---- >>> from c41811.config import MappingConfigData >>> data = MappingConfigData({"key": "value"}) 路径存在时返回值 >>> data.setdefault("key") 'value' 路径不存在时返回默认值None并填充到原始数据 >>> print(data.setdefault("not exists")) None >>> data MappingConfigData({'key': 'value', 'not exists': None}) 自定义默认值 >>> data.setdefault("with default", default="default value") 'default value' >>> data MappingConfigData({'key': 'value', 'not exists': None, 'with default': 'default value'}) .. versionchanged:: 0.2.0 重命名参数 ``get_raw`` 为 ``return_raw_value`` 重命名 ``set_default`` 为 ``setdefault`` .. py:method:: unset(path: config.abc.PathLike) -> Self 确保路径不存在 (删除路径,但是找不到路径时不会报错) :param path: 路径 :type path: PathLike :return: 返回当前实例便于链式调用 :rtype: Self :raise ConfigDataReadOnlyError: 配置数据为只读 :raise ConfigDataTypeError: 配置数据类型错误 .. versionadded:: 0.1.2 .. py:attribute:: __hash__ :value: None .. py:attribute:: __slots__ :value: () .. py:attribute:: _data :type: D .. py:attribute:: _read_only :type: bool | None :value: False .. py:property:: data :type: D 配置的原始数据*快照* .. py:property:: data_read_only :type: bool | None 配置数据是否为只读 :return: 配置数据是否为只读 :rtype: bool | None .. versionadded:: 0.1.3 .. versionchanged:: 0.1.5 改为抽象属性 .. py:property:: read_only :type: bool | None 配置数据是否为 ``只读模式`` :return: 配置数据是否为 ``只读模式`` :rtype: bool | None .. py:class:: BasicSingleConfigData(data: D) Bases: :py:obj:`BasicConfigData`\ [\ :py:obj:`BasicSingleConfigData.D`\ ], :py:obj:`abc.ABC` 单文件配置数据基类 .. versionadded:: 0.2.0 :param data: 配置的原始数据 :type data: Any .. py:method:: __bool__() -> bool .. py:method:: __deepcopy__(memo: dict[str, Any]) -> Self .. py:method:: __eq__(other: Any) -> bool .. py:method:: __format__(format_spec: str) -> str .. py:method:: __repr__() -> str .. py:method:: __str__() -> str .. py:method:: freeze(freeze: bool | None = None) -> Self 冻结配置数据 (切换只读模式) :param freeze: 是否冻结配置数据, 为 :py:const:`None` 时进行切换 :type freeze: bool | None :return: 返回当前实例便于链式调用 :rtype: Self .. versionadded:: 0.1.5 .. py:method:: from_data(*args: Any, **kwargs: Any) -> Self :classmethod: 提供创建同类型配置数据的快捷方式 :return: 新的配置数据 :rtype: Self .. note:: 套壳 ``__init__`` 主要是为了方便内部快速创建与传入的ABCConfigData同类型的对象 例如: .. code-block:: python type(instance)(data) 可以简写为 .. code-block:: python instance.from_data(data) .. versionchanged:: 0.2.0 现在会自适应初始化参数 .. py:attribute:: __hash__ :value: None .. py:attribute:: __slots__ :value: () .. py:attribute:: _data :type: D .. py:attribute:: _read_only :type: bool | None :value: False .. py:property:: data :type: D 配置的原始数据*快照* .. py:property:: data_read_only :type: bool | None 配置数据是否为只读 :return: 配置数据是否为只读 :rtype: bool | None .. versionadded:: 0.1.3 .. versionchanged:: 0.1.5 改为抽象属性 .. py:property:: read_only :type: bool | None 配置数据是否为 ``只读模式`` :return: 配置数据是否为 ``只读模式`` :rtype: bool | None .. py:class:: ConfigFile(initial_config: D | Any, *, config_format: str | None = None) Bases: :py:obj:`config.abc.ABCConfigFile`\ [\ :py:obj:`ConfigFile.D`\ ] 配置文件类 :param initial_config: 配置数据 :type initial_config: D :param config_format: 配置文件的格式 :type config_format: str | None .. caution:: 本身并未对 ``initial_config`` 参数进行深拷贝,但是 :py:class:`ConfigDataFactory` 分发的类可能会将其深拷贝 .. versionchanged:: 0.2.0 现在会自动尝试使用 :py:class:`ConfigDataFactory` 转换 ``initial_config`` 参数 重命名参数 ``config_data`` 为 ``initial_config`` .. py:method:: __bool__() -> bool .. py:method:: __eq__(other: Any) -> bool .. py:method:: __repr__() -> str .. py:method:: initialize(processor_pool: config.abc.ABCSLProcessorPool, namespace: str, file_name: str, config_format: str, *processor_args: Any, **processor_kwargs: Any) -> Self :classmethod: 初始化一个受SL处理器支持的配置文件 :param processor_pool: 配置池 :type processor_pool: ABCSLProcessorPool :param namespace: 文件命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str :param config_format: 配置文件的格式 :type config_format: str :return: 配置对象 :rtype: Self :raise UnsupportedConfigFormatError: 不支持的配置格式 .. versionadded:: 0.2.0 .. py:method:: load(processor_pool: config.abc.ABCSLProcessorPool, namespace: str, file_name: str, config_format: str, *processor_args: Any, **processor_kwargs: Any) -> Self :classmethod: 从SL处理器加载配置 :param processor_pool: 配置池 :type processor_pool: ABCSLProcessorPool :param namespace: 文件命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str :param config_format: 配置文件的格式 :type config_format: str :return: 配置对象 :rtype: Self :raise UnsupportedConfigFormatError: 不支持的配置格式 .. versionchanged:: 0.2.0 重命名 ``config_pool`` 为 ``processor_pool`` .. py:method:: save(processor_pool: config.abc.ABCSLProcessorPool, namespace: str, file_name: str, config_format: str | None = None, *processor_args: Any, **processor_kwargs: Any) -> None 使用SL处理保存配置 :param processor_pool: 配置池 :type processor_pool: ABCSLProcessorPool :param namespace: 文件命名空间 :type namespace: str :param file_name: 文件名 :type file_name: str :param config_format: 配置文件的格式 :type config_format: str | None :raise UnsupportedConfigFormatError: 不支持的配置格式 .. versionchanged:: 0.2.0 重命名 ``config_pool`` 为 ``processor_pool`` .. py:attribute:: __hash__ :value: None .. py:attribute:: __slots__ :value: () .. py:attribute:: _config :type: D .. py:attribute:: _config_format :type: str | None :value: None .. py:property:: config :type: D :return: 配置数据 .. caution:: 未默认做深拷贝,可能导致非预期行为 .. versionchanged:: 0.2.0 重命名属性 ``data`` 为 ``config`` .. py:property:: config_format :type: str | None 配置文件的格式 .. py:class:: PHelper Bases: :py:obj:`config.abc.ABCProcessorHelper` 处理器助手类 .. py:method:: calc_path(root_path: str, namespace: str, file_name: str | None = None) -> str :staticmethod: 处理配置文件对应的文件路径 file_name为None时,返回文件所在的目录 :param root_path: 保存的根目录 :type root_path: str :param namespace: 配置的命名空间 :type namespace: str :param file_name: 配置文件名 :type file_name: str | None :return: 配置文件路径 :rtype: str .. py:attribute:: __slots__ :value: ()