tketool.core 1.3.4__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.
- tketool_core-1.3.4/PKG-INFO +62 -0
- tketool_core-1.3.4/README.md +21 -0
- tketool_core-1.3.4/pyproject.toml +46 -0
- tketool_core-1.3.4/setup.cfg +4 -0
- tketool_core-1.3.4/src/tketool/JConfig.py +498 -0
- tketool_core-1.3.4/src/tketool/__init__.py +8 -0
- tketool_core-1.3.4/src/tketool/buffer/__init__.py +0 -0
- tketool_core-1.3.4/src/tketool/buffer/bufferbase.py +505 -0
- tketool_core-1.3.4/src/tketool/buffer/local_many.py +141 -0
- tketool_core-1.3.4/src/tketool/buffer/local_one.py +174 -0
- tketool_core-1.3.4/src/tketool/buffer/local_onesqlite.py +229 -0
- tketool_core-1.3.4/src/tketool/buffer/redis.py +158 -0
- tketool_core-1.3.4/src/tketool/cmd_utils.py +307 -0
- tketool_core-1.3.4/src/tketool/files.py +548 -0
- tketool_core-1.3.4/src/tketool/hash_util.py +203 -0
- tketool_core-1.3.4/src/tketool/utils/MultiTask.py +172 -0
- tketool_core-1.3.4/src/tketool/utils/__init__.py +1 -0
- tketool_core-1.3.4/src/tketool/utils/chunkfile.py +568 -0
- tketool_core-1.3.4/src/tketool/utils/consolescreen.py +1527 -0
- tketool_core-1.3.4/src/tketool/utils/consolescreen_utils.py +415 -0
- tketool_core-1.3.4/src/tketool/utils/cost.py +190 -0
- tketool_core-1.3.4/src/tketool/utils/dashboard_argsbase_ui.py +1046 -0
- tketool_core-1.3.4/src/tketool/utils/docker_utils.py +505 -0
- tketool_core-1.3.4/src/tketool/utils/excel_utils.py +842 -0
- tketool_core-1.3.4/src/tketool/utils/log_format.py +214 -0
- tketool_core-1.3.4/src/tketool/utils/minio_utils.py +355 -0
- tketool_core-1.3.4/src/tketool/utils/pip_utils.py +691 -0
- tketool_core-1.3.4/src/tketool/utils/progressbar.py +781 -0
- tketool_core-1.3.4/src/tketool/utils/word_utils.py +1191 -0
- tketool_core-1.3.4/src/tketool/utils/zip_utils.py +460 -0
- tketool_core-1.3.4/src/tketool/version.py +7 -0
- tketool_core-1.3.4/src/tketool.core.egg-info/PKG-INFO +62 -0
- tketool_core-1.3.4/src/tketool.core.egg-info/SOURCES.txt +34 -0
- tketool_core-1.3.4/src/tketool.core.egg-info/dependency_links.txt +1 -0
- tketool_core-1.3.4/src/tketool.core.egg-info/requires.txt +32 -0
- tketool_core-1.3.4/src/tketool.core.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tketool.core
|
|
3
|
+
Version: 1.3.4
|
|
4
|
+
Summary: Core configuration, file, buffer, and utility APIs for tketool
|
|
5
|
+
Author-email: Ke <jiangke1207@icloud.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://pypi.org/project/tketool.core/
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
Requires-Dist: paramiko<6,>=4
|
|
16
|
+
Provides-Extra: storage
|
|
17
|
+
Requires-Dist: minio<8,>=7.2.20; extra == "storage"
|
|
18
|
+
Requires-Dist: redis<9,>=6; extra == "storage"
|
|
19
|
+
Provides-Extra: documents
|
|
20
|
+
Requires-Dist: pandas<4,>=2.2; extra == "documents"
|
|
21
|
+
Requires-Dist: openpyxl<4,>=3.1.5; extra == "documents"
|
|
22
|
+
Requires-Dist: python-docx<2,>=1.2; extra == "documents"
|
|
23
|
+
Provides-Extra: console
|
|
24
|
+
Requires-Dist: blessed<2,>=1.20; extra == "console"
|
|
25
|
+
Requires-Dist: prettytable<4,>=3.12; extra == "console"
|
|
26
|
+
Requires-Dist: wcwidth<1,>=0.2.13; extra == "console"
|
|
27
|
+
Provides-Extra: docker
|
|
28
|
+
Requires-Dist: docker<8,>=7; extra == "docker"
|
|
29
|
+
Provides-Extra: test
|
|
30
|
+
Requires-Dist: pytest<9,>=8; extra == "test"
|
|
31
|
+
Provides-Extra: all
|
|
32
|
+
Requires-Dist: minio<8,>=7.2.20; extra == "all"
|
|
33
|
+
Requires-Dist: redis<9,>=6; extra == "all"
|
|
34
|
+
Requires-Dist: pandas<4,>=2.2; extra == "all"
|
|
35
|
+
Requires-Dist: openpyxl<4,>=3.1.5; extra == "all"
|
|
36
|
+
Requires-Dist: python-docx<2,>=1.2; extra == "all"
|
|
37
|
+
Requires-Dist: blessed<2,>=1.20; extra == "all"
|
|
38
|
+
Requires-Dist: prettytable<4,>=3.12; extra == "all"
|
|
39
|
+
Requires-Dist: wcwidth<1,>=0.2.13; extra == "all"
|
|
40
|
+
Requires-Dist: docker<8,>=7; extra == "all"
|
|
41
|
+
|
|
42
|
+
# tketool.core
|
|
43
|
+
|
|
44
|
+
`tketool.core` contains the shared configuration, file, buffer, command, and
|
|
45
|
+
utility APIs used by the other tketool distributions.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install tketool.core
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from tketool import ConfigManager, read_file, write_file
|
|
53
|
+
from tketool.buffer.local_onesqlite import init_db
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Optional dependencies are grouped by feature:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install "tketool.core[storage]"
|
|
60
|
+
pip install "tketool.core[documents]"
|
|
61
|
+
pip install "tketool.core[console]"
|
|
62
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# tketool.core
|
|
2
|
+
|
|
3
|
+
`tketool.core` contains the shared configuration, file, buffer, command, and
|
|
4
|
+
utility APIs used by the other tketool distributions.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pip install tketool.core
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from tketool import ConfigManager, read_file, write_file
|
|
12
|
+
from tketool.buffer.local_onesqlite import init_db
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Optional dependencies are grouped by feature:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install "tketool.core[storage]"
|
|
19
|
+
pip install "tketool.core[documents]"
|
|
20
|
+
pip install "tketool.core[console]"
|
|
21
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tketool.core"
|
|
7
|
+
version = "1.3.4"
|
|
8
|
+
description = "Core configuration, file, buffer, and utility APIs for tketool"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{ name = "Ke", email = "jiangke1207@icloud.com" }]
|
|
13
|
+
dependencies = ["paramiko>=4,<6"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.10",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
storage = ["minio>=7.2.20,<8", "redis>=6,<9"]
|
|
24
|
+
documents = ["pandas>=2.2,<4", "openpyxl>=3.1.5,<4", "python-docx>=1.2,<2"]
|
|
25
|
+
console = ["blessed>=1.20,<2", "prettytable>=3.12,<4", "wcwidth>=0.2.13,<1"]
|
|
26
|
+
docker = ["docker>=7,<8"]
|
|
27
|
+
test = ["pytest>=8,<9"]
|
|
28
|
+
all = [
|
|
29
|
+
"minio>=7.2.20,<8",
|
|
30
|
+
"redis>=6,<9",
|
|
31
|
+
"pandas>=2.2,<4",
|
|
32
|
+
"openpyxl>=3.1.5,<4",
|
|
33
|
+
"python-docx>=1.2,<2",
|
|
34
|
+
"blessed>=1.20,<2",
|
|
35
|
+
"prettytable>=3.12,<4",
|
|
36
|
+
"wcwidth>=0.2.13,<1",
|
|
37
|
+
"docker>=7,<8",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://pypi.org/project/tketool.core/"
|
|
42
|
+
|
|
43
|
+
[tool.setuptools.packages.find]
|
|
44
|
+
where = ["src"]
|
|
45
|
+
include = ["tketool*"]
|
|
46
|
+
namespaces = true
|
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
# pass_generate
|
|
2
|
+
import os
|
|
3
|
+
from typing import Optional, Dict, Any, Union
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ConfigManager:
|
|
8
|
+
"""
|
|
9
|
+
配置管理器类(单例模式),用于处理配置文件的读取、写入和管理。
|
|
10
|
+
|
|
11
|
+
支持以下特性:
|
|
12
|
+
- 单例模式,确保全局只有一个配置管理器实例
|
|
13
|
+
- 从配置文件读取键值对配置
|
|
14
|
+
- 环境变量优先级支持(文件 -> 环境变量 -> 默认值)
|
|
15
|
+
- 自动创建不存在的配置文件
|
|
16
|
+
- 动态添加配置项
|
|
17
|
+
- 配置项的保存、删除和重载
|
|
18
|
+
- 动态切换配置文件路径
|
|
19
|
+
|
|
20
|
+
配置文件格式:
|
|
21
|
+
```
|
|
22
|
+
# 这是注释
|
|
23
|
+
database_host=localhost
|
|
24
|
+
database_port=5432
|
|
25
|
+
api_key="your_api_key_here"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
使用示例:
|
|
29
|
+
```python
|
|
30
|
+
# 获取单例配置管理器
|
|
31
|
+
config = ConfigManager()
|
|
32
|
+
# 或者
|
|
33
|
+
config = get_config_instance()
|
|
34
|
+
|
|
35
|
+
# 切换配置文件
|
|
36
|
+
config.set_config_filepath("/path/to/new/config.jconfig")
|
|
37
|
+
|
|
38
|
+
# 获取配置,优先级:文件 -> 环境变量 -> 默认值
|
|
39
|
+
db_host = config.get_config("database_host", "localhost")
|
|
40
|
+
|
|
41
|
+
# 检查配置是否存在
|
|
42
|
+
if config.has_config("api_key"):
|
|
43
|
+
api_key = config.get_config("api_key")
|
|
44
|
+
|
|
45
|
+
# 设置配置
|
|
46
|
+
config.set_config("new_setting", "value")
|
|
47
|
+
|
|
48
|
+
# 删除配置
|
|
49
|
+
config.delete_config("old_setting")
|
|
50
|
+
|
|
51
|
+
# 重新加载配置文件
|
|
52
|
+
config.reload()
|
|
53
|
+
```
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
_instance = None
|
|
57
|
+
_initialized = False
|
|
58
|
+
|
|
59
|
+
def __new__(cls, config_file_path: str = None):
|
|
60
|
+
"""
|
|
61
|
+
实现单例模式。
|
|
62
|
+
|
|
63
|
+
参数:
|
|
64
|
+
config_file_path (str, optional): 配置文件路径,仅在首次创建实例时有效
|
|
65
|
+
|
|
66
|
+
返回:
|
|
67
|
+
ConfigManager: 单例实例
|
|
68
|
+
"""
|
|
69
|
+
if cls._instance is None:
|
|
70
|
+
cls._instance = super(ConfigManager, cls).__new__(cls)
|
|
71
|
+
return cls._instance
|
|
72
|
+
|
|
73
|
+
def __init__(self, config_file_path: str = None) -> None:
|
|
74
|
+
"""
|
|
75
|
+
初始化配置管理器(单例模式)。
|
|
76
|
+
|
|
77
|
+
参数:
|
|
78
|
+
config_file_path (str, optional): 配置文件的路径,可以是相对路径或绝对路径。
|
|
79
|
+
如果为None,使用默认的 config.jconfig
|
|
80
|
+
如果文件不存在,将自动创建一个空的配置文件。
|
|
81
|
+
|
|
82
|
+
示例:
|
|
83
|
+
```python
|
|
84
|
+
config = ConfigManager("./config/app.jconfig")
|
|
85
|
+
config = ConfigManager("/etc/myapp/config.jconfig")
|
|
86
|
+
# 使用默认配置文件
|
|
87
|
+
config = ConfigManager()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
注意:
|
|
91
|
+
- 由于是单例模式,config_file_path 参数仅在首次创建实例时有效
|
|
92
|
+
- 如需切换配置文件,请使用 set_config_filepath() 方法
|
|
93
|
+
- 配置文件使用UTF-8编码
|
|
94
|
+
- 支持以#开头的注释行
|
|
95
|
+
- 键值对格式:key=value
|
|
96
|
+
- 值可以用双引号或单引号包围
|
|
97
|
+
"""
|
|
98
|
+
# 避免重复初始化
|
|
99
|
+
if self._initialized:
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
self._config_map: Dict[str, str] = {}
|
|
103
|
+
|
|
104
|
+
# 设置默认配置文件路径
|
|
105
|
+
if config_file_path is None:
|
|
106
|
+
config_file_path = os.path.join(os.getcwd(), "config.jconfig")
|
|
107
|
+
|
|
108
|
+
self._config_file_path: str = config_file_path
|
|
109
|
+
self._load_configs()
|
|
110
|
+
self._initialized = True
|
|
111
|
+
|
|
112
|
+
def set_config_filepath(self, config_file_path: str) -> None:
|
|
113
|
+
"""
|
|
114
|
+
设置新的配置文件路径并重新加载配置。
|
|
115
|
+
|
|
116
|
+
参数:
|
|
117
|
+
config_file_path (str): 新的配置文件路径
|
|
118
|
+
|
|
119
|
+
示例:
|
|
120
|
+
```python
|
|
121
|
+
config = get_config_instance()
|
|
122
|
+
config.set_config_filepath("/path/to/new/config.jconfig")
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
注意:
|
|
126
|
+
- 会立即重新加载新的配置文件
|
|
127
|
+
- 原有的内存配置将被清空
|
|
128
|
+
- 如果新文件不存在,会自动创建
|
|
129
|
+
"""
|
|
130
|
+
print(f"切换配置文件路径: {self._config_file_path} -> {config_file_path}")
|
|
131
|
+
self._config_file_path = config_file_path
|
|
132
|
+
self._load_configs()
|
|
133
|
+
|
|
134
|
+
def _load_configs(self) -> None:
|
|
135
|
+
"""
|
|
136
|
+
加载配置文件中的配置项。
|
|
137
|
+
|
|
138
|
+
如果配置文件存在,读取文件中的每一行,解析键值对并存储到内存字典中。
|
|
139
|
+
支持注释行(以#开头)和空行的过滤。
|
|
140
|
+
|
|
141
|
+
如果配置文件不存在,创建一个新的空配置文件。
|
|
142
|
+
|
|
143
|
+
文件格式说明:
|
|
144
|
+
- 每行一个键值对,格式为:key=value
|
|
145
|
+
- 支持注释行,以#开头
|
|
146
|
+
- 键和值的前后空格会被自动去除
|
|
147
|
+
- 值可以用单引号或双引号包围
|
|
148
|
+
"""
|
|
149
|
+
self._config_map.clear()
|
|
150
|
+
|
|
151
|
+
if os.path.exists(self._config_file_path):
|
|
152
|
+
try:
|
|
153
|
+
with open(self._config_file_path, "r", encoding="utf-8") as f:
|
|
154
|
+
lines = f.readlines()
|
|
155
|
+
for line_num, line in enumerate(lines, 1):
|
|
156
|
+
line = line.strip()
|
|
157
|
+
# 跳过空行和注释行
|
|
158
|
+
if not line or line.startswith("#"):
|
|
159
|
+
continue
|
|
160
|
+
|
|
161
|
+
key, sep, value = line.partition("=")
|
|
162
|
+
if sep: # 确保包含等号
|
|
163
|
+
key = self._sanitize_string(key.strip())
|
|
164
|
+
value = self._sanitize_string(value.strip())
|
|
165
|
+
if key: # 确保键不为空
|
|
166
|
+
self._config_map[key] = value
|
|
167
|
+
else:
|
|
168
|
+
print(f"警告: 配置文件第{line_num}行格式错误: {line}")
|
|
169
|
+
except Exception as e:
|
|
170
|
+
print(f"加载配置文件失败: {e}")
|
|
171
|
+
raise
|
|
172
|
+
else:
|
|
173
|
+
# 创建空的配置文件
|
|
174
|
+
try:
|
|
175
|
+
os.makedirs(os.path.dirname(self._config_file_path), exist_ok=True)
|
|
176
|
+
with open(self._config_file_path, "w", encoding="utf-8") as f:
|
|
177
|
+
f.write("# 配置文件\n")
|
|
178
|
+
except Exception as e:
|
|
179
|
+
print(f"创建配置文件失败: {e}")
|
|
180
|
+
raise
|
|
181
|
+
|
|
182
|
+
@staticmethod
|
|
183
|
+
def _sanitize_string(s: str) -> str:
|
|
184
|
+
"""
|
|
185
|
+
清理字符串,去除前后的引号和空格。
|
|
186
|
+
|
|
187
|
+
参数:
|
|
188
|
+
s (str): 待处理的字符串
|
|
189
|
+
|
|
190
|
+
返回:
|
|
191
|
+
str: 处理后的字符串
|
|
192
|
+
|
|
193
|
+
示例:
|
|
194
|
+
```python
|
|
195
|
+
result = ConfigManager._sanitize_string(' "hello world" ')
|
|
196
|
+
# result = "hello world"
|
|
197
|
+
|
|
198
|
+
result = ConfigManager._sanitize_string("'test'")
|
|
199
|
+
# result = "test"
|
|
200
|
+
```
|
|
201
|
+
"""
|
|
202
|
+
if not s:
|
|
203
|
+
return s
|
|
204
|
+
|
|
205
|
+
s = s.strip()
|
|
206
|
+
# 去除前后的引号
|
|
207
|
+
if len(s) >= 2:
|
|
208
|
+
if (s.startswith('"') and s.endswith('"')) or (
|
|
209
|
+
s.startswith("'") and s.endswith("'")
|
|
210
|
+
):
|
|
211
|
+
s = s[1:-1]
|
|
212
|
+
|
|
213
|
+
return s
|
|
214
|
+
|
|
215
|
+
def has_config(self, key: str, use_env: bool = True) -> bool:
|
|
216
|
+
"""
|
|
217
|
+
检查指定的配置键是否存在。
|
|
218
|
+
|
|
219
|
+
参数:
|
|
220
|
+
key (str): 配置键名
|
|
221
|
+
|
|
222
|
+
返回:
|
|
223
|
+
bool: 如果配置键存在返回True,否则返回False
|
|
224
|
+
|
|
225
|
+
示例:
|
|
226
|
+
```python
|
|
227
|
+
if config.has_config("database_host"):
|
|
228
|
+
host = config.get_config("database_host")
|
|
229
|
+
```
|
|
230
|
+
"""
|
|
231
|
+
if use_env:
|
|
232
|
+
env_value = os.environ.get(key)
|
|
233
|
+
if env_value is not None:
|
|
234
|
+
return True
|
|
235
|
+
|
|
236
|
+
return key in self._config_map
|
|
237
|
+
|
|
238
|
+
def get_config(
|
|
239
|
+
self,
|
|
240
|
+
key: str,
|
|
241
|
+
default_value: str = "",
|
|
242
|
+
use_env: bool = True,
|
|
243
|
+
raise_if_missing: bool = False,
|
|
244
|
+
) -> str:
|
|
245
|
+
"""
|
|
246
|
+
获取指定键的配置值,支持多级优先级查找。
|
|
247
|
+
|
|
248
|
+
查找优先级:
|
|
249
|
+
1. 配置文件中的值
|
|
250
|
+
2. 环境变量中的值(如果use_env为True)
|
|
251
|
+
3. 默认值
|
|
252
|
+
|
|
253
|
+
参数:
|
|
254
|
+
key (str): 配置键名
|
|
255
|
+
default_value (str): 默认值,当配置项不存在时使用
|
|
256
|
+
use_env (bool): 是否检查环境变量,默认为True
|
|
257
|
+
raise_if_missing (bool): 当配置项不存在且无默认值时是否抛出异常
|
|
258
|
+
|
|
259
|
+
返回:
|
|
260
|
+
str: 配置值
|
|
261
|
+
|
|
262
|
+
异常:
|
|
263
|
+
KeyError: 当raise_if_missing为True且配置项不存在时抛出
|
|
264
|
+
|
|
265
|
+
示例:
|
|
266
|
+
```python
|
|
267
|
+
# 基本用法
|
|
268
|
+
host = config.get_config("database_host", "localhost")
|
|
269
|
+
|
|
270
|
+
# 不使用环境变量
|
|
271
|
+
port = config.get_config("database_port", "5432", use_env=False)
|
|
272
|
+
|
|
273
|
+
# 必须存在的配置
|
|
274
|
+
api_key = config.get_config("api_key", raise_if_missing=True)
|
|
275
|
+
```
|
|
276
|
+
"""
|
|
277
|
+
# 1. 首先检查配置文件
|
|
278
|
+
if key in self._config_map:
|
|
279
|
+
return self._config_map[key]
|
|
280
|
+
|
|
281
|
+
# 2. 检查环境变量
|
|
282
|
+
if use_env:
|
|
283
|
+
env_value = os.environ.get(key)
|
|
284
|
+
if env_value is not None:
|
|
285
|
+
print(f"使用环境变量 {key}={env_value}")
|
|
286
|
+
return env_value
|
|
287
|
+
|
|
288
|
+
# 3. 检查是否必须存在
|
|
289
|
+
if raise_if_missing and not default_value:
|
|
290
|
+
raise KeyError(f"配置项 '{key}' 不存在且未提供默认值")
|
|
291
|
+
|
|
292
|
+
# 4. 使用默认值并添加到配置文件
|
|
293
|
+
if default_value or not raise_if_missing:
|
|
294
|
+
print(f"配置项 '{key}' 不存在,使用默认值: {default_value}")
|
|
295
|
+
self.set_config(key, default_value)
|
|
296
|
+
return default_value
|
|
297
|
+
|
|
298
|
+
return default_value
|
|
299
|
+
|
|
300
|
+
def set_config(self, key: str, value: str) -> None:
|
|
301
|
+
"""
|
|
302
|
+
设置配置项的值,同时更新内存和文件。
|
|
303
|
+
|
|
304
|
+
参数:
|
|
305
|
+
key (str): 配置键名
|
|
306
|
+
value (str): 配置值
|
|
307
|
+
|
|
308
|
+
示例:
|
|
309
|
+
```python
|
|
310
|
+
config.set_config("database_host", "192.168.1.100")
|
|
311
|
+
config.set_config("debug_mode", "true")
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
注意:
|
|
315
|
+
- 会立即写入配置文件
|
|
316
|
+
- 如果键已存在,会覆盖原有值
|
|
317
|
+
"""
|
|
318
|
+
# 更新内存中的配置
|
|
319
|
+
self._config_map[key] = value
|
|
320
|
+
|
|
321
|
+
# 保存到文件
|
|
322
|
+
self._save_to_file()
|
|
323
|
+
|
|
324
|
+
def delete_config(self, key: str) -> bool:
|
|
325
|
+
"""
|
|
326
|
+
删除指定的配置项。
|
|
327
|
+
|
|
328
|
+
参数:
|
|
329
|
+
key (str): 要删除的配置键名
|
|
330
|
+
|
|
331
|
+
返回:
|
|
332
|
+
bool: 如果成功删除返回True,如果键不存在返回False
|
|
333
|
+
|
|
334
|
+
示例:
|
|
335
|
+
```python
|
|
336
|
+
if config.delete_config("old_setting"):
|
|
337
|
+
print("配置项已删除")
|
|
338
|
+
else:
|
|
339
|
+
print("配置项不存在")
|
|
340
|
+
```
|
|
341
|
+
"""
|
|
342
|
+
if key in self._config_map:
|
|
343
|
+
del self._config_map[key]
|
|
344
|
+
self._save_to_file()
|
|
345
|
+
print(f"已删除配置项: {key}")
|
|
346
|
+
return True
|
|
347
|
+
return False
|
|
348
|
+
|
|
349
|
+
def reload(self) -> None:
|
|
350
|
+
"""
|
|
351
|
+
重新加载配置文件,丢弃内存中的修改。
|
|
352
|
+
|
|
353
|
+
示例:
|
|
354
|
+
```python
|
|
355
|
+
# 重新从文件加载配置
|
|
356
|
+
config.reload()
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
注意:
|
|
360
|
+
这会丢弃所有未保存的内存中的配置修改。
|
|
361
|
+
"""
|
|
362
|
+
print("重新加载配置文件")
|
|
363
|
+
self._load_configs()
|
|
364
|
+
|
|
365
|
+
def get_all_configs(self) -> Dict[str, str]:
|
|
366
|
+
"""
|
|
367
|
+
获取所有配置项的副本。
|
|
368
|
+
|
|
369
|
+
返回:
|
|
370
|
+
Dict[str, str]: 包含所有配置项的字典
|
|
371
|
+
|
|
372
|
+
示例:
|
|
373
|
+
```python
|
|
374
|
+
all_configs = config.get_all_configs()
|
|
375
|
+
for key, value in all_configs.items():
|
|
376
|
+
print(f"{key} = {value}")
|
|
377
|
+
```
|
|
378
|
+
"""
|
|
379
|
+
return self._config_map.copy()
|
|
380
|
+
|
|
381
|
+
def get_current_filepath(self) -> str:
|
|
382
|
+
"""
|
|
383
|
+
获取当前使用的配置文件路径。
|
|
384
|
+
|
|
385
|
+
返回:
|
|
386
|
+
str: 当前配置文件的路径
|
|
387
|
+
|
|
388
|
+
示例:
|
|
389
|
+
```python
|
|
390
|
+
current_path = config.get_current_filepath()
|
|
391
|
+
print(f"当前配置文件: {current_path}")
|
|
392
|
+
```
|
|
393
|
+
"""
|
|
394
|
+
return self._config_file_path
|
|
395
|
+
|
|
396
|
+
def _save_to_file(self) -> None:
|
|
397
|
+
"""
|
|
398
|
+
将当前内存中的配置保存到文件。
|
|
399
|
+
|
|
400
|
+
内部方法,在设置或删除配置时自动调用。
|
|
401
|
+
"""
|
|
402
|
+
try:
|
|
403
|
+
with open(self._config_file_path, "w", encoding="utf-8") as f:
|
|
404
|
+
f.write("# 配置文件\n")
|
|
405
|
+
f.write("# 格式:key=value\n")
|
|
406
|
+
f.write("# 支持注释行(以#开头)\n\n")
|
|
407
|
+
|
|
408
|
+
for key, value in sorted(self._config_map.items()):
|
|
409
|
+
# 如果值包含特殊字符,用引号包围
|
|
410
|
+
if " " in value or "=" in value or value.startswith("#"):
|
|
411
|
+
f.write(f'{key}="{value}"\n')
|
|
412
|
+
else:
|
|
413
|
+
f.write(f"{key}={value}\n")
|
|
414
|
+
except Exception as e:
|
|
415
|
+
print(f"保存配置文件失败: {e}")
|
|
416
|
+
raise
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def get_config_instance() -> ConfigManager:
|
|
420
|
+
"""
|
|
421
|
+
获取配置管理器的单例实例。
|
|
422
|
+
|
|
423
|
+
返回:
|
|
424
|
+
ConfigManager: 配置管理器单例实例
|
|
425
|
+
|
|
426
|
+
示例:
|
|
427
|
+
```python
|
|
428
|
+
# 获取单例配置管理器
|
|
429
|
+
config = get_config_instance()
|
|
430
|
+
|
|
431
|
+
# 所有调用都返回同一个实例
|
|
432
|
+
config1 = get_config_instance()
|
|
433
|
+
config2 = get_config_instance()
|
|
434
|
+
assert config1 is config2 # True
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
注意:
|
|
438
|
+
- 使用单例模式确保全局只有一个配置管理器实例
|
|
439
|
+
- 首次调用时会使用默认的配置文件路径(当前目录下的 config.jconfig)
|
|
440
|
+
- 如需使用不同的配置文件,请使用 set_config_filepath() 方法
|
|
441
|
+
"""
|
|
442
|
+
return ConfigManager()
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def clear_config_cache() -> None:
|
|
446
|
+
"""
|
|
447
|
+
清除配置实例缓存,主要用于测试。
|
|
448
|
+
|
|
449
|
+
注意: 由于改为单例模式,此方法会重置单例实例。
|
|
450
|
+
|
|
451
|
+
示例:
|
|
452
|
+
```python
|
|
453
|
+
# 重置单例实例,下次获取时会重新创建
|
|
454
|
+
clear_config_cache()
|
|
455
|
+
```
|
|
456
|
+
"""
|
|
457
|
+
ConfigManager._instance = None
|
|
458
|
+
ConfigManager._initialized = False
|
|
459
|
+
print("已重置配置管理器单例实例")
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
# 改进建议和未来功能扩展:
|
|
463
|
+
#
|
|
464
|
+
# 1. 数据类型支持:
|
|
465
|
+
# - 添加 get_int(), get_float(), get_bool() 等类型转换方法
|
|
466
|
+
# - 支持列表和字典类型的配置项
|
|
467
|
+
# - 添加配置项的类型验证
|
|
468
|
+
#
|
|
469
|
+
# 2. 配置文件格式扩展:
|
|
470
|
+
# - 支持 JSON, YAML, TOML 等格式
|
|
471
|
+
# - 支持配置分组/节([section])
|
|
472
|
+
# - 支持配置项的继承和覆盖
|
|
473
|
+
#
|
|
474
|
+
# 3. 高级功能:
|
|
475
|
+
# - 配置文件的版本控制和迁移
|
|
476
|
+
# - 配置项的加密支持
|
|
477
|
+
# - 配置变更的监听和回调
|
|
478
|
+
# - 配置项的验证规则(正则表达式、范围检查等)
|
|
479
|
+
#
|
|
480
|
+
# 4. 性能优化:
|
|
481
|
+
# - 文件变更监控,自动重载
|
|
482
|
+
# - 惰性加载大型配置文件
|
|
483
|
+
# - 配置项的缓存策略
|
|
484
|
+
#
|
|
485
|
+
# 5. 安全性增强:
|
|
486
|
+
# - 敏感配置项的掩码显示
|
|
487
|
+
# - 配置文件的权限检查
|
|
488
|
+
# - 配置项的访问日志
|
|
489
|
+
#
|
|
490
|
+
# 6. 开发工具:
|
|
491
|
+
# - 配置项的自动补全
|
|
492
|
+
# - 配置文件的语法检查
|
|
493
|
+
# - 配置项的使用统计和分析
|
|
494
|
+
#
|
|
495
|
+
# 7. 集成功能:
|
|
496
|
+
# - 与命令行参数的集成
|
|
497
|
+
# - 与远程配置中心的集成
|
|
498
|
+
# - 与容器环境的集成(Docker secrets, Kubernetes ConfigMap)
|
|
File without changes
|