tretool 0.2.1__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.
tretool-0.2.1/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2018 The Python Packaging Authority
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
tretool-0.2.1/PKG-INFO ADDED
@@ -0,0 +1,28 @@
1
+ Metadata-Version: 2.4
2
+ Name: tretool
3
+ Version: 0.2.1
4
+ Summary: 一个有着许多功能的Python工具库
5
+ Author-email: Jemy <sh_ljr_2013@163.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/pypa/sampleproject
8
+ Project-URL: Issues, https://github.com/pypa/sampleproject/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: license-file
15
+
16
+ # tretool
17
+
18
+ ## tretool - Python多功能工具库
19
+
20
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)
21
+
22
+ **tretool** 是一个集成常用功能的Python工具库。
23
+
24
+ ## 📦 安装
25
+
26
+ ### 使用pip
27
+ bash
28
+ ```pip install tretool
@@ -0,0 +1,13 @@
1
+ # tretool
2
+
3
+ ## tretool - Python多功能工具库
4
+
5
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)
6
+
7
+ **tretool** 是一个集成常用功能的Python工具库。
8
+
9
+ ## 📦 安装
10
+
11
+ ### 使用pip
12
+ bash
13
+ ```pip install tretool
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = [
3
+ "chardet",
4
+ "packaging",
5
+ "rich",
6
+ "setuptools >= 77.0.3"
7
+ ]
8
+ build-backend = "setuptools.build_meta"
9
+
10
+ [project]
11
+ name = "tretool"
12
+ version = "0.2.1"
13
+ authors = [
14
+ { name="Jemy", email="sh_ljr_2013@163.com" },
15
+ ]
16
+ description = "一个有着许多功能的Python工具库"
17
+ readme = "README.md"
18
+ requires-python = ">=3.10"
19
+ classifiers = [
20
+ "Programming Language :: Python :: 3",
21
+ "Operating System :: OS Independent",
22
+ ]
23
+ license = "MIT"
24
+ license-files = ["LICEN[CS]E*"]
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/pypa/sampleproject"
28
+ Issues = "https://github.com/pypa/sampleproject/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,27 @@
1
+ """
2
+ # tretool
3
+
4
+ ## tretool - Python多功能工具库
5
+
6
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)
7
+
8
+ **tretool** 是一个集成常用功能的Python工具库。
9
+ """
10
+
11
+ from . import config
12
+
13
+ from . import encoding
14
+
15
+ from . import jsonlib
16
+
17
+ from . import markfunc
18
+ from . import memorizeTools
19
+
20
+ from . import path
21
+ from . import platformlib
22
+ from . import plugin
23
+
24
+ from . import timelib
25
+ from . import transform
26
+
27
+ from . import writeLog
@@ -0,0 +1,262 @@
1
+ """
2
+ ### 配置管理库,提供安全的键值对存储和访问机制
3
+
4
+ 特性:
5
+ - 类型安全的设置和获取
6
+ - 默认值支持
7
+ - 批量操作支持
8
+ - 配置项存在性检查
9
+ - 防止意外覆盖
10
+ - 配置文件持久化
11
+ - 配置变更回调
12
+ """
13
+
14
+ import json
15
+ import os
16
+ from typing import Any, Callable, Dict, Optional
17
+
18
+ class Config:
19
+ """
20
+ 配置管理类,提供安全的键值对存储和访问机制
21
+
22
+ 特性:
23
+ - 类型安全的设置和获取
24
+ - 默认值支持
25
+ - 批量操作支持
26
+ - 配置项存在性检查
27
+ - 防止意外覆盖
28
+ - 配置变更通知
29
+
30
+ 使用示例:
31
+ ```
32
+ config = Config({"theme": "dark"})
33
+ config.set_config("font_size", 14)
34
+ theme = config.get_config("theme", default="light")
35
+
36
+ # 添加配置变更监听
37
+ def on_config_change(key, old_value, new_value):
38
+ print(f"配置变更: {key} 从 {old_value} 改为 {new_value}")
39
+
40
+ config.add_change_listener(on_config_change)
41
+
42
+ # 保存和加载配置
43
+ config.save_to_file("settings.json")
44
+ new_config = Config.load_from_file("settings.json")
45
+ ```
46
+ """
47
+
48
+ def __init__(self, initial_config: Optional[Dict[str, Any]] = None):
49
+ """
50
+ 初始化配置存储
51
+
52
+ 参数:
53
+ initial_config: 初始配置字典 (可选)
54
+ """
55
+ self.config_dict = initial_config.copy() if initial_config else {}
56
+ self._lock = False # 防止意外修改的锁
57
+ self._change_listeners = [] # 配置变更监听器列表
58
+
59
+ def __str__(self) -> str:
60
+ """返回配置的可读字符串表示"""
61
+ return json.dumps(self.config_dict, indent=2, ensure_ascii=False)
62
+
63
+ def __repr__(self) -> str:
64
+ """返回配置的正式表示"""
65
+ return f"Config({self.config_dict})"
66
+
67
+ def __contains__(self, item: str) -> bool:
68
+ """检查配置项是否存在"""
69
+ return item in self.config_dict
70
+
71
+ def __len__(self) -> int:
72
+ """返回配置项的数量"""
73
+ return len(self.config_dict)
74
+
75
+ def add_change_listener(self, listener: Callable[[str, Any, Any], None]):
76
+ """
77
+ 添加配置变更监听器
78
+
79
+ 参数:
80
+ listener: 回调函数,格式为 func(key, old_value, new_value)
81
+ """
82
+ if listener not in self._change_listeners:
83
+ self._change_listeners.append(listener)
84
+
85
+ def remove_change_listener(self, listener: Callable[[str, Any, Any], None]):
86
+ """移除配置变更监听器"""
87
+ if listener in self._change_listeners:
88
+ self._change_listeners.remove(listener)
89
+
90
+ def _notify_change(self, key: str, old_value: Any, new_value: Any):
91
+ """通知所有监听器配置变更"""
92
+ for listener in self._change_listeners:
93
+ try:
94
+ listener(key, old_value, new_value)
95
+ except Exception as e:
96
+ print(f"配置变更通知错误: {e}")
97
+
98
+ def get_config(self, item: str, default: Any = None) -> Any:
99
+ """
100
+ 安全获取配置项
101
+
102
+ 参数:
103
+ item: 配置键名
104
+ default: 当键不存在时返回的默认值
105
+
106
+ 返回:
107
+ 配置值或默认值
108
+ """
109
+ return self.config_dict.get(item, default)
110
+
111
+ def set_config(self, item: str, value: Any) -> bool:
112
+ """
113
+ 设置配置项
114
+
115
+ 参数:
116
+ item: 配置键名
117
+ value: 配置值
118
+
119
+ 返回:
120
+ True 设置成功, False 设置失败
121
+ """
122
+ if self._lock:
123
+ print(f"警告: 配置系统已锁定,无法修改 '{item}'")
124
+ return False
125
+
126
+ old_value = self.config_dict.get(item)
127
+ self.config_dict[item] = value
128
+
129
+ # 通知变更
130
+ self._notify_change(item, old_value, value)
131
+ return True
132
+
133
+ def delete_config(self, item: str) -> bool:
134
+ """
135
+ 删除配置项
136
+
137
+ 参数:
138
+ item: 要删除的配置键名
139
+
140
+ 返回:
141
+ True 删除成功, False 键不存在
142
+ """
143
+ if item in self.config_dict:
144
+ old_value = self.config_dict[item]
145
+ del self.config_dict[item]
146
+
147
+ # 通知变更 (值为 None 表示删除)
148
+ self._notify_change(item, old_value, None)
149
+ return True
150
+ return False
151
+
152
+ def save_to_file(self, filename: str) -> bool:
153
+ """
154
+ 保存配置到文件
155
+
156
+ 参数:
157
+ filename: 文件名
158
+
159
+ 返回:
160
+ True 保存成功, False 保存失败
161
+ """
162
+ try:
163
+ with open(filename, 'w', encoding='utf-8') as f:
164
+ json.dump(self.get_all_configs(), f, indent=2, ensure_ascii=False)
165
+ return True
166
+ except (IOError, TypeError) as e:
167
+ print(f"保存配置失败: {e}")
168
+ return False
169
+
170
+ @classmethod
171
+ def load_from_file(cls, filename: str) -> Optional['Config']:
172
+ """
173
+ 从文件加载配置
174
+
175
+ 参数:
176
+ filename: 文件名
177
+
178
+ 返回:
179
+ 加载成功的 Config 实例,失败返回 None
180
+ """
181
+ if not os.path.exists(filename):
182
+ print(f"配置文件不存在: {filename}")
183
+ return None
184
+
185
+ try:
186
+ with open(filename, 'r', encoding='utf-8') as f:
187
+ config_data = json.load(f)
188
+ return cls(config_data)
189
+ except (IOError, json.JSONDecodeError) as e:
190
+ print(f"加载配置失败: {e}")
191
+ return None
192
+
193
+ def has_config(self, item: str) -> bool:
194
+ """检查配置项是否存在"""
195
+ return item in self.config_dict
196
+
197
+ def lock_config(self):
198
+ """锁定配置防止修改"""
199
+ self._lock = True
200
+
201
+ def unlock_config(self):
202
+ """解锁配置允许修改"""
203
+ self._lock = False
204
+
205
+ def is_locked(self) -> bool:
206
+ """检查配置是否已锁定"""
207
+ return self._lock
208
+
209
+ def bulk_update(self, update_dict: Dict[str, Any]) -> bool:
210
+ """
211
+ 批量更新配置
212
+
213
+ 参数:
214
+ update_dict: 包含多个键值对的字典
215
+
216
+ 返回:
217
+ True 更新成功, False 更新失败
218
+ """
219
+ if self._lock:
220
+ print("警告: 配置系统已锁定,批量更新被拒绝")
221
+ return False
222
+
223
+ # 记录变更
224
+ changes = {}
225
+ for key, value in update_dict.items():
226
+ old_value = self.config_dict.get(key)
227
+ self.config_dict[key] = value
228
+ changes[key] = (old_value, value)
229
+
230
+ # 批量通知变更
231
+ for key, (old_value, new_value) in changes.items():
232
+ self._notify_change(key, old_value, new_value)
233
+
234
+ return True
235
+
236
+ def get_all_configs(self) -> Dict[str, Any]:
237
+ """获取所有配置的副本"""
238
+ return self.config_dict.copy()
239
+
240
+ def reset_config(self, new_config: Optional[Dict[str, Any]] = None) -> None:
241
+ """
242
+ 重置所有配置
243
+
244
+ 参数:
245
+ new_config: 新的配置字典 (可选,默认清空)
246
+ """
247
+ if self._lock:
248
+ print("警告: 配置系统已锁定,无法重置")
249
+ return
250
+
251
+ # 记录所有变更(删除)
252
+ for key in list(self.config_dict.keys()):
253
+ old_value = self.config_dict[key]
254
+ self._notify_change(key, old_value, None)
255
+
256
+ # 重置配置
257
+ self.config_dict = new_config.copy() if new_config else {}
258
+
259
+ # 通知所有新配置项
260
+ for key, value in self.config_dict.items():
261
+ self._notify_change(key, None, value)
262
+
@@ -0,0 +1,92 @@
1
+ import chardet
2
+
3
+ from typing import Union, BinaryIO
4
+
5
+ def detect_encoding(
6
+ input_data: Union[bytes, str, BinaryIO],
7
+ sample_size: int = 1024,
8
+ fallback_encoding: str = 'utf-8'
9
+ ) -> str:
10
+ """
11
+ 自动检测文本数据的字符编码
12
+
13
+ 参数:
14
+ input_data: 可以是以下类型之一:
15
+ - bytes: 原始字节数据
16
+ - str: 字符串(将尝试重新编码检测)
17
+ - BinaryIO: 文件对象(将读取前sample_size字节)
18
+ sample_size: 从文件/大数据中采样的字节数(默认1024)
19
+ fallback_encoding: 无法检测时使用的回退编码(默认'utf-8')
20
+
21
+ 返回:
22
+ 检测到的编码名称字符串
23
+
24
+ 示例:
25
+ # 检测字节数据编码
26
+ detect_encoding(b'\xc3\xa9chantillon')
27
+
28
+ # 检测文件编码
29
+ with open('file.txt', 'rb') as f:
30
+ encoding = detect_encoding(f)
31
+ """
32
+ raw_data = _get_sample_data(input_data, sample_size)
33
+
34
+ if not raw_data:
35
+ return fallback_encoding
36
+
37
+ try:
38
+ # 使用chardet进行编码检测
39
+ result = chardet.detect(raw_data)
40
+ confidence = result['confidence']
41
+ encoding = result['encoding'].lower()
42
+
43
+ # 验证检测结果
44
+ if confidence > 0.9:
45
+ return encoding
46
+ if confidence > 0.7 and validate_encoding(raw_data, encoding):
47
+ return encoding
48
+
49
+ # 尝试常见编码验证
50
+ for enc in ['utf-8', 'latin-1', 'gbk', 'gb2312', 'big5']:
51
+ if validate_encoding(raw_data, enc):
52
+ return enc
53
+
54
+ except Exception:
55
+ pass
56
+
57
+ return fallback_encoding
58
+
59
+
60
+ def _get_sample_data(
61
+ input_data: Union[bytes, str, BinaryIO],
62
+ sample_size: int
63
+ ) -> bytes:
64
+ """获取用于检测的样本数据"""
65
+ if isinstance(input_data, bytes):
66
+ return input_data[:sample_size]
67
+
68
+ if isinstance(input_data, str):
69
+ try:
70
+ return input_data.encode('latin-1', errors='ignore')[:sample_size]
71
+ except:
72
+ return b''
73
+
74
+ if hasattr(input_data, 'read'):
75
+ try:
76
+ pos = input_data.tell()
77
+ data = input_data.read(sample_size)
78
+ input_data.seek(pos) # 重置文件指针
79
+ return data if isinstance(data, bytes) else b''
80
+ except:
81
+ return b''
82
+
83
+ return b''
84
+
85
+
86
+ def validate_encoding(data: bytes, encoding: str) -> bool:
87
+ """验证编码是否有效"""
88
+ try:
89
+ data.decode(encoding, errors='strict')
90
+ return True
91
+ except:
92
+ return False