tretool 0.2.1__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {tretool-0.2.1 → tretool-0.3.0}/PKG-INFO +8 -4
  2. {tretool-0.2.1 → tretool-0.3.0}/README.md +1 -1
  3. {tretool-0.2.1 → tretool-0.3.0}/pyproject.toml +19 -3
  4. tretool-0.3.0/src/tretool/__init__.py +52 -0
  5. tretool-0.3.0/src/tretool/config.py +498 -0
  6. tretool-0.3.0/src/tretool/decoratorlib.py +423 -0
  7. tretool-0.3.0/src/tretool/encoding.py +421 -0
  8. tretool-0.3.0/src/tretool/httplib.py +730 -0
  9. tretool-0.3.0/src/tretool/jsonlib.py +767 -0
  10. tretool-0.3.0/src/tretool/logger.py +712 -0
  11. {tretool-0.2.1 → tretool-0.3.0}/src/tretool/mathlib.py +0 -33
  12. {tretool-0.2.1 → tretool-0.3.0}/src/tretool/path.py +19 -0
  13. tretool-0.3.0/src/tretool/platformlib.py +487 -0
  14. tretool-0.3.0/src/tretool/plugin.py +548 -0
  15. tretool-0.3.0/src/tretool/smartCache.py +569 -0
  16. tretool-0.3.0/src/tretool/tasklib.py +730 -0
  17. tretool-0.3.0/src/tretool/transform/pdf.py +574 -0
  18. {tretool-0.2.1 → tretool-0.3.0}/src/tretool.egg-info/PKG-INFO +8 -4
  19. {tretool-0.2.1 → tretool-0.3.0}/src/tretool.egg-info/SOURCES.txt +6 -3
  20. tretool-0.3.0/src/tretool.egg-info/requires.txt +4 -0
  21. tretool-0.2.1/src/tretool/__init__.py +0 -27
  22. tretool-0.2.1/src/tretool/config.py +0 -262
  23. tretool-0.2.1/src/tretool/encoding.py +0 -92
  24. tretool-0.2.1/src/tretool/jsonlib.py +0 -299
  25. tretool-0.2.1/src/tretool/markfunc.py +0 -152
  26. tretool-0.2.1/src/tretool/memorizeTools.py +0 -24
  27. tretool-0.2.1/src/tretool/platformlib.py +0 -332
  28. tretool-0.2.1/src/tretool/plugin.py +0 -348
  29. tretool-0.2.1/src/tretool/transform/pdf.py +0 -396
  30. tretool-0.2.1/src/tretool/writeLog.py +0 -69
  31. {tretool-0.2.1 → tretool-0.3.0}/LICENSE +0 -0
  32. {tretool-0.2.1 → tretool-0.3.0}/setup.cfg +0 -0
  33. {tretool-0.2.1 → tretool-0.3.0}/src/tretool/plugin/plu.py +0 -0
  34. {tretool-0.2.1 → tretool-0.3.0}/src/tretool/timelib.py +0 -0
  35. {tretool-0.2.1 → tretool-0.3.0}/src/tretool/transform/__init__.py +0 -0
  36. {tretool-0.2.1 → tretool-0.3.0}/src/tretool.egg-info/dependency_links.txt +0 -0
  37. {tretool-0.2.1 → tretool-0.3.0}/src/tretool.egg-info/top_level.txt +0 -0
  38. {tretool-0.2.1 → tretool-0.3.0}/tests/tests.py +0 -0
@@ -1,23 +1,27 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tretool
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: 一个有着许多功能的Python工具库
5
5
  Author-email: Jemy <sh_ljr_2013@163.com>
6
6
  License-Expression: MIT
7
- Project-URL: Homepage, https://github.com/pypa/sampleproject
8
- Project-URL: Issues, https://github.com/pypa/sampleproject/issues
7
+ Project-URL: Homepage, https://github.com/jemy/sampleproject
8
+ Project-URL: Issues, https://github.com/jemy/sampleproject/issues
9
+ Keywords: tool,tools,utility,utilities,productivity
9
10
  Classifier: Programming Language :: Python :: 3
10
11
  Classifier: Operating System :: OS Independent
11
12
  Requires-Python: >=3.10
12
13
  Description-Content-Type: text/markdown
13
14
  License-File: LICENSE
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest; extra == "dev"
17
+ Requires-Dist: pipreqs; extra == "dev"
14
18
  Dynamic: license-file
15
19
 
16
20
  # tretool
17
21
 
18
22
  ## tretool - Python多功能工具库
19
23
 
20
- [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)
24
+ [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/)
21
25
 
22
26
  **tretool** 是一个集成常用功能的Python工具库。
23
27
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## tretool - Python多功能工具库
4
4
 
5
- [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)
5
+ [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/)
6
6
 
7
7
  **tretool** 是一个集成常用功能的Python工具库。
8
8
 
@@ -2,20 +2,28 @@
2
2
  requires = [
3
3
  "chardet",
4
4
  "packaging",
5
+ "pdfminer",
6
+ "pdf2image",
7
+ "pillow",
8
+ "PyPDF2",
9
+ "psutil",
5
10
  "rich",
11
+ "tabula",
12
+
6
13
  "setuptools >= 77.0.3"
7
14
  ]
8
15
  build-backend = "setuptools.build_meta"
9
16
 
10
17
  [project]
11
18
  name = "tretool"
12
- version = "0.2.1"
19
+ version = "0.3.0"
13
20
  authors = [
14
21
  { name="Jemy", email="sh_ljr_2013@163.com" },
15
22
  ]
16
23
  description = "一个有着许多功能的Python工具库"
17
24
  readme = "README.md"
18
25
  requires-python = ">=3.10"
26
+ keywords = ["tool", "tools", "utility", "utilities", "productivity"]
19
27
  classifiers = [
20
28
  "Programming Language :: Python :: 3",
21
29
  "Operating System :: OS Independent",
@@ -23,6 +31,14 @@ classifiers = [
23
31
  license = "MIT"
24
32
  license-files = ["LICEN[CS]E*"]
25
33
 
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "pytest",
37
+ "pipreqs"
38
+ ]
39
+
26
40
  [project.urls]
27
- Homepage = "https://github.com/pypa/sampleproject"
28
- Issues = "https://github.com/pypa/sampleproject/issues"
41
+ Homepage = "https://github.com/jemy/sampleproject"
42
+ Issues = "https://github.com/jemy/sampleproject/issues"
43
+
44
+ [project.scripts]
@@ -0,0 +1,52 @@
1
+ """
2
+ # tretool
3
+
4
+ ## tretool - Python多功能工具库
5
+
6
+ [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/)
7
+
8
+ **tretool** 是一个集成常用功能的Python工具库。
9
+ """
10
+
11
+ import sys
12
+
13
+ MIN_PY_VERSION = (3, 10)
14
+
15
+ if sys.version_info >= MIN_PY_VERSION:
16
+ from . import config
17
+
18
+ from . import decoratorlib
19
+
20
+ from . import encoding
21
+
22
+ from . import httplib
23
+
24
+ from . import jsonlib
25
+
26
+ from . import logger
27
+
28
+ from . import path
29
+ from . import platformlib
30
+ from . import plugin
31
+
32
+ from . import smartCache
33
+
34
+ from . import timelib
35
+ from . import transform
36
+
37
+ else:
38
+ current_version = f"{sys.version_info.major}.{sys.version_info.minor}"
39
+ required_version = f"{MIN_PY_VERSION[0]}.{MIN_PY_VERSION[1]}"
40
+
41
+ raise RuntimeError(
42
+ f"\n\n"
43
+ f"不兼容的Python版本\n\n"
44
+ f"Tretool需要Python {required_version}+ (检测到: Python {current_version})\n"
45
+ f"请执行以下操作之一:\n"
46
+ f"1. 升级Python到{required_version}或更高版本\n"
47
+ f"2. 使用兼容的Tretool版本\n\n"
48
+ f"升级Python推荐方法:\n"
49
+ f"- 使用pyenv: `pyenv install 3.10.x`\n"
50
+ f"- 从官网下载: https://www.python.org/downloads/\n"
51
+ f"- 使用conda: `conda install python=3.10`"
52
+ )
@@ -0,0 +1,498 @@
1
+ import json
2
+ import os
3
+ import threading
4
+ from typing import Any, Callable, Dict, Optional, Union, List, TypeVar, Generic
5
+ from dataclasses import dataclass
6
+ from enum import Enum, auto
7
+ from pathlib import Path
8
+ import logging
9
+ from copy import deepcopy
10
+
11
+ # 配置日志
12
+ logging.basicConfig(level=logging.INFO)
13
+ logger = logging.getLogger(__name__)
14
+
15
+ T = TypeVar('T')
16
+
17
+ class ConfigError(Exception):
18
+ """配置基础异常"""
19
+ pass
20
+
21
+ class ConfigLockedError(ConfigError):
22
+ """配置被锁定异常"""
23
+ pass
24
+
25
+ class ConfigValidationError(ConfigError):
26
+ """配置验证失败异常"""
27
+ pass
28
+
29
+ class ConfigOperation(Enum):
30
+ """配置操作类型"""
31
+ SET = auto()
32
+ DELETE = auto()
33
+ RESET = auto()
34
+
35
+ @dataclass
36
+ class ConfigChangeEvent:
37
+ """配置变更事件"""
38
+ key: str
39
+ old_value: Any
40
+ new_value: Any
41
+ operation: ConfigOperation
42
+
43
+ class ConfigValidator(Generic[T]):
44
+ """配置验证器基类"""
45
+ def validate(self, value: Any) -> T:
46
+ """验证并转换配置值"""
47
+ raise NotImplementedError
48
+
49
+ class IntValidator(ConfigValidator[int]):
50
+ """整数验证器"""
51
+ def __init__(self, min_value: Optional[int] = None, max_value: Optional[int] = None):
52
+ self.min = min_value
53
+ self.max = max_value
54
+
55
+ def validate(self, value: Any) -> int:
56
+ try:
57
+ val = int(value)
58
+ if self.min is not None and val < self.min:
59
+ raise ConfigValidationError(f"值 {val} 小于最小值 {self.min}")
60
+ if self.max is not None and val > self.max:
61
+ raise ConfigValidationError(f"值 {val} 大于最大值 {self.max}")
62
+ return val
63
+ except (ValueError, TypeError) as e:
64
+ raise ConfigValidationError(f"无效的整数值: {value}") from e
65
+
66
+ class Config:
67
+ """
68
+ 增强版配置管理类,提供类型安全、线程安全的配置管理
69
+
70
+ 主要特性:
71
+ - 类型安全的配置存取
72
+ - 配置变更监听和通知
73
+ - 配置验证和转换
74
+ - 多格式持久化支持
75
+ - 原子操作和事务支持
76
+ - 配置版本控制
77
+ - 环境变量集成
78
+ """
79
+
80
+ def __init__(
81
+ self,
82
+ initial_config: Optional[Dict[str, Any]] = None,
83
+ validators: Optional[Dict[str, ConfigValidator]] = None,
84
+ config_dir: Optional[Union[str, Path]] = None,
85
+ env_prefix: Optional[str] = None
86
+ ):
87
+ """
88
+ 初始化配置存储
89
+
90
+ 参数:
91
+ initial_config: 初始配置字典
92
+ validators: 配置验证器字典 {key: validator}
93
+ config_dir: 配置文件存储目录
94
+ env_prefix: 环境变量前缀
95
+ """
96
+ self._data = deepcopy(initial_config) if initial_config else {}
97
+ self._validators = validators or {}
98
+ self._lock = threading.Lock()
99
+ self._change_listeners = []
100
+ self._config_dir = Path(config_dir) if config_dir else None
101
+ self._env_prefix = f"{env_prefix}_" if env_prefix else ""
102
+ self._version = 1
103
+ self._transaction_stack = []
104
+
105
+ # 从环境变量加载配置
106
+ self._load_from_env()
107
+
108
+ def __str__(self) -> str:
109
+ """返回配置的可读字符串表示"""
110
+ return json.dumps(self._data, indent=2, ensure_ascii=False)
111
+
112
+ def __repr__(self) -> str:
113
+ """返回配置的正式表示"""
114
+ return f"Config({self._data})"
115
+
116
+ def __contains__(self, key: str) -> bool:
117
+ """检查配置项是否存在"""
118
+ return key in self._data
119
+
120
+ def __len__(self) -> int:
121
+ """返回配置项的数量"""
122
+ return len(self._data)
123
+
124
+ def __enter__(self):
125
+ """进入事务上下文"""
126
+ self.begin_transaction()
127
+ return self
128
+
129
+ def __exit__(self, exc_type, exc_val, exc_tb):
130
+ """退出事务上下文"""
131
+ if exc_type is None:
132
+ self.commit_transaction()
133
+ else:
134
+ self.rollback_transaction()
135
+
136
+ @property
137
+ def version(self) -> int:
138
+ """获取配置版本"""
139
+ return self._version
140
+
141
+ def begin_transaction(self):
142
+ """开始一个配置事务"""
143
+ with self._lock:
144
+ self._transaction_stack.append(deepcopy(self._data))
145
+
146
+ def commit_transaction(self):
147
+ """提交当前事务"""
148
+ with self._lock:
149
+ if not self._transaction_stack:
150
+ raise ConfigError("没有活跃的事务可提交")
151
+ self._transaction_stack.pop()
152
+ self._version += 1
153
+
154
+ def rollback_transaction(self):
155
+ """回滚当前事务"""
156
+ with self._lock:
157
+ if not self._transaction_stack:
158
+ raise ConfigError("没有活跃的事务可回滚")
159
+ self._data = self._transaction_stack.pop()
160
+
161
+ def add_change_listener(self, listener: Callable[[ConfigChangeEvent], None]):
162
+ """
163
+ 添加配置变更监听器
164
+
165
+ 参数:
166
+ listener: 回调函数,接收 ConfigChangeEvent 参数
167
+ """
168
+ with self._lock:
169
+ if listener not in self._change_listeners:
170
+ self._change_listeners.append(listener)
171
+
172
+ def remove_change_listener(self, listener: Callable[[ConfigChangeEvent], None]):
173
+ """移除配置变更监听器"""
174
+ with self._lock:
175
+ if listener in self._change_listeners:
176
+ self._change_listeners.remove(listener)
177
+
178
+ def _notify_change(self, event: ConfigChangeEvent):
179
+ """通知所有监听器配置变更"""
180
+ with self._lock:
181
+ listeners = self._change_listeners.copy()
182
+
183
+ for listener in listeners:
184
+ try:
185
+ listener(event)
186
+ except Exception as e:
187
+ logger.error(f"配置变更通知错误: {e}", exc_info=True)
188
+
189
+ def get(self, key: str, default: Any = None, validate: bool = True) -> Any:
190
+ """
191
+ 获取配置项
192
+
193
+ 参数:
194
+ key: 配置键名
195
+ default: 默认值
196
+ validate: 是否验证返回值
197
+
198
+ 返回:
199
+ 配置值或默认值
200
+
201
+ 异常:
202
+ ConfigValidationError: 验证失败
203
+ """
204
+ with self._lock:
205
+ value = self._data.get(key, default)
206
+
207
+ if validate and key in self._validators:
208
+ try:
209
+ return self._validators[key].validate(value)
210
+ except ConfigValidationError as e:
211
+ logger.warning(f"配置验证失败 [{key}]: {e}")
212
+ raise
213
+
214
+ return value
215
+
216
+ def set(self, key: str, value: Any, validate: bool = True) -> bool:
217
+ """
218
+ 设置配置项
219
+
220
+ 参数:
221
+ key: 配置键名
222
+ value: 配置值
223
+ validate: 是否验证值
224
+
225
+ 返回:
226
+ True 设置成功, False 设置失败
227
+
228
+ 异常:
229
+ ConfigValidationError: 验证失败
230
+ ConfigLockedError: 配置被锁定
231
+ """
232
+ if validate and key in self._validators:
233
+ value = self._validators[key].validate(value)
234
+
235
+ with self._lock:
236
+ if not self._transaction_stack:
237
+ raise ConfigError("必须在事务中修改配置")
238
+
239
+ old_value = self._data.get(key)
240
+ self._data[key] = value
241
+
242
+ # 通知变更
243
+ event = ConfigChangeEvent(
244
+ key=key,
245
+ old_value=old_value,
246
+ new_value=value,
247
+ operation=ConfigOperation.SET
248
+ )
249
+ self._notify_change(event)
250
+
251
+ return True
252
+
253
+ def delete(self, key: str) -> bool:
254
+ """
255
+ 删除配置项
256
+
257
+ 参数:
258
+ key: 要删除的配置键名
259
+
260
+ 返回:
261
+ True 删除成功, False 键不存在
262
+
263
+ 异常:
264
+ ConfigLockedError: 配置被锁定
265
+ """
266
+ with self._lock:
267
+ if not self._transaction_stack:
268
+ raise ConfigError("必须在事务中修改配置")
269
+
270
+ if key not in self._data:
271
+ return False
272
+
273
+ old_value = self._data[key]
274
+ del self._data[key]
275
+
276
+ # 通知变更
277
+ event = ConfigChangeEvent(
278
+ key=key,
279
+ old_value=old_value,
280
+ new_value=None,
281
+ operation=ConfigOperation.DELETE
282
+ )
283
+ self._notify_change(event)
284
+
285
+ return True
286
+
287
+ def has(self, key: str) -> bool:
288
+ """检查配置项是否存在"""
289
+ with self._lock:
290
+ return key in self._data
291
+
292
+ def bulk_update(self, updates: Dict[str, Any], validate: bool = True) -> bool:
293
+ """
294
+ 批量更新配置
295
+
296
+ 参数:
297
+ updates: 包含多个键值对的字典
298
+ validate: 是否验证值
299
+
300
+ 返回:
301
+ True 更新成功
302
+
303
+ 异常:
304
+ ConfigValidationError: 验证失败
305
+ ConfigLockedError: 配置被锁定
306
+ """
307
+ if validate:
308
+ for key, value in updates.items():
309
+ if key in self._validators:
310
+ updates[key] = self._validators[key].validate(value)
311
+
312
+ with self._lock:
313
+ if not self._transaction_stack:
314
+ raise ConfigError("必须在事务中修改配置")
315
+
316
+ # 记录变更
317
+ changes = []
318
+ for key, value in updates.items():
319
+ old_value = self._data.get(key)
320
+ self._data[key] = value
321
+ changes.append(ConfigChangeEvent(
322
+ key=key,
323
+ old_value=old_value,
324
+ new_value=value,
325
+ operation=ConfigOperation.SET
326
+ ))
327
+
328
+ # 批量通知变更
329
+ for event in changes:
330
+ self._notify_change(event)
331
+
332
+ return True
333
+
334
+ def reset(self, new_config: Optional[Dict[str, Any]] = None) -> None:
335
+ """
336
+ 重置所有配置
337
+
338
+ 参数:
339
+ new_config: 新的配置字典 (可选,默认清空)
340
+
341
+ 异常:
342
+ ConfigLockedError: 配置被锁定
343
+ """
344
+ with self._lock:
345
+ if not self._transaction_stack:
346
+ raise ConfigError("必须在事务中修改配置")
347
+
348
+ # 记录所有变更(删除)
349
+ delete_events = []
350
+ for key in list(self._data.keys()):
351
+ delete_events.append(ConfigChangeEvent(
352
+ key=key,
353
+ old_value=self._data[key],
354
+ new_value=None,
355
+ operation=ConfigOperation.DELETE
356
+ ))
357
+
358
+ # 重置配置
359
+ new_data = deepcopy(new_config) if new_config else {}
360
+ self._data = new_data
361
+
362
+ # 通知所有删除和新配置项
363
+ for event in delete_events:
364
+ self._notify_change(event)
365
+
366
+ for key, value in self._data.items():
367
+ self._notify_change(ConfigChangeEvent(
368
+ key=key,
369
+ old_value=None,
370
+ new_value=value,
371
+ operation=ConfigOperation.SET
372
+ ))
373
+
374
+ def to_dict(self) -> Dict[str, Any]:
375
+ """获取所有配置的深拷贝"""
376
+ with self._lock:
377
+ return deepcopy(self._data)
378
+
379
+ def save(self, filename: Optional[str] = None, format: str = 'json') -> bool:
380
+ """
381
+ 保存配置到文件
382
+
383
+ 参数:
384
+ filename: 文件名 (可选,使用默认配置目录)
385
+ format: 文件格式 ('json', 'yaml')
386
+
387
+ 返回:
388
+ True 保存成功, False 保存失败
389
+ """
390
+ if filename is None and self._config_dir is None:
391
+ raise ConfigError("未指定文件名且未设置配置目录")
392
+
393
+ filepath = Path(filename) if filename else self._config_dir / f"config.{format}"
394
+ filepath.parent.mkdir(parents=True, exist_ok=True)
395
+
396
+ try:
397
+ with filepath.open('w', encoding='utf-8') as f:
398
+ if format == 'json':
399
+ json.dump(self.to_dict(), f, indent=2, ensure_ascii=False)
400
+ elif format == 'yaml':
401
+ import yaml
402
+ yaml.safe_dump(self.to_dict(), f, allow_unicode=True)
403
+ else:
404
+ raise ConfigError(f"不支持的格式: {format}")
405
+ return True
406
+ except Exception as e:
407
+ logger.error(f"保存配置失败: {e}", exc_info=True)
408
+ return False
409
+
410
+ @classmethod
411
+ def load(
412
+ cls,
413
+ filename: str,
414
+ validators: Optional[Dict[str, ConfigValidator]] = None,
415
+ config_dir: Optional[Union[str, Path]] = None,
416
+ env_prefix: Optional[str] = None
417
+ ) -> 'Config':
418
+ """
419
+ 从文件加载配置
420
+
421
+ 参数:
422
+ filename: 文件名
423
+ validators: 配置验证器
424
+ config_dir: 配置目录
425
+ env_prefix: 环境变量前缀
426
+
427
+ 返回:
428
+ 加载的 Config 实例
429
+
430
+ 异常:
431
+ ConfigError: 加载失败
432
+ """
433
+ filepath = Path(filename)
434
+ if not filepath.is_absolute() and config_dir is not None:
435
+ filepath = Path(config_dir) / filename
436
+
437
+ try:
438
+ with filepath.open('r', encoding='utf-8') as f:
439
+ if filepath.suffix.lower() == '.json':
440
+ data = json.load(f)
441
+ elif filepath.suffix.lower() in ('.yaml', '.yml'):
442
+ import yaml
443
+ data = yaml.safe_load(f)
444
+ else:
445
+ raise ConfigError(f"不支持的文件格式: {filepath.suffix}")
446
+
447
+ return cls(
448
+ initial_config=data,
449
+ validators=validators,
450
+ config_dir=config_dir,
451
+ env_prefix=env_prefix
452
+ )
453
+ except Exception as e:
454
+ raise ConfigError(f"加载配置失败: {e}") from e
455
+
456
+ def _load_from_env(self):
457
+ """从环境变量加载配置"""
458
+ if not self._env_prefix:
459
+ return
460
+
461
+ for key, value in os.environ.items():
462
+ if key.startswith(self._env_prefix):
463
+ config_key = key[len(self._env_prefix):].lower()
464
+ try:
465
+ # 尝试解析JSON格式的环境变量
466
+ parsed_value = json.loads(value)
467
+ self._data[config_key] = parsed_value
468
+ except json.JSONDecodeError:
469
+ # 普通字符串值
470
+ self._data[config_key] = value
471
+
472
+ def register_validator(self, key: str, validator: ConfigValidator):
473
+ """注册配置验证器"""
474
+ with self._lock:
475
+ self._validators[key] = validator
476
+
477
+ def unregister_validator(self, key: str):
478
+ """移除配置验证器"""
479
+ with self._lock:
480
+ if key in self._validators:
481
+ del self._validators[key]
482
+
483
+ def get_validator(self, key: str) -> Optional[ConfigValidator]:
484
+ """获取配置验证器"""
485
+ with self._lock:
486
+ return self._validators.get(key)
487
+
488
+ def validate_all(self) -> Dict[str, Union[Any, Exception]]:
489
+ """验证所有配置项,返回验证结果字典"""
490
+ results = {}
491
+ with self._lock:
492
+ for key, validator in self._validators.items():
493
+ if key in self._data:
494
+ try:
495
+ results[key] = validator.validate(self._data[key])
496
+ except Exception as e:
497
+ results[key] = e
498
+ return results