ezKit 1.10.0__py3-none-any.whl → 1.10.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
ezKit/utils.py CHANGED
@@ -9,12 +9,11 @@ import time
9
9
  import tomllib
10
10
  from copy import deepcopy
11
11
  from itertools import islice
12
- from multiprocessing import Pool, Process
12
+ from multiprocessing import Pool
13
13
  from multiprocessing.pool import ThreadPool
14
14
  from pathlib import Path
15
15
  from shutil import rmtree
16
- from threading import Thread
17
- from typing import Any, Callable, List, Optional, Union
16
+ from typing import Any, Callable, List, Union
18
17
  from urllib.parse import ParseResult, urlparse
19
18
  from uuid import uuid4
20
19
 
@@ -742,31 +741,23 @@ def parent_dir(
742
741
  # --------------------------------------------------------------------------------------------------
743
742
 
744
743
 
745
- def retry(
746
- times: int,
747
- func: Callable,
748
- **kwargs
749
- ):
744
+ def retry(func: Callable, times: int = 3, **kwargs):
750
745
  """重试"""
746
+
751
747
  # 函数传递参数: https://stackoverflow.com/a/803632
752
748
  # callable() 判断类型是非为函数: https://stackoverflow.com/a/624939
753
- try:
754
- _num = 0
755
- while True:
756
- # 重试次数判断 (0 表示无限次数, 这里条件使用 > 0, 表示有限次数)
757
- if times > 0:
758
- _num += 1
759
- if _num > times:
760
- return
761
- # 执行函数
762
- try:
763
- return func(**kwargs)
764
- except Exception as e:
765
- logger.exception(e)
749
+
750
+ for attempt in range(times):
751
+ try:
752
+ # 执行函数并结果
753
+ return func(**kwargs)
754
+ except Exception as e:
755
+ logger.exception(e)
756
+ if attempt < (times - 1):
766
757
  logger.info('retrying ...')
767
- continue
768
- except Exception as e:
769
- logger.exception(e)
758
+ else:
759
+ logger.error("all retries failed")
760
+ return False
770
761
 
771
762
 
772
763
  # --------------------------------------------------------------------------------------------------
@@ -1199,65 +1190,61 @@ def delete_directory(
1199
1190
  # --------------------------------------------------------------------------------------------------
1200
1191
 
1201
1192
 
1202
- def process_pool(
1193
+ def processor(
1203
1194
  process_func: Callable,
1204
- process_data: Any = None,
1195
+ process_data: List[Any],
1205
1196
  process_num: int = 2,
1206
1197
  thread: bool = False,
1207
1198
  **kwargs
1208
- ) -> list | bool:
1209
- """
1210
- 多线程(MultiThread) | 多进程(MultiProcess)
1211
- """
1212
- # ThreadPool 线程池
1199
+ ) -> Union[List[Any], bool]:
1200
+ """使用多线程或多进程对数据进行并行处理"""
1201
+
1202
+ # :param process_func: 处理函数
1203
+ # :param process_data: 待处理数据列表
1204
+ # :param process_num: 并行数量
1205
+ # :param thread: 是否使用多线程
1206
+ # :param kwargs: 其他可选参数传递给线程池或进程池
1207
+ # :return: 处理后的结果列表或 False(异常情况)
1208
+ #
1209
+ # MultiThread 多线程
1210
+ # MultiProcess 多进程
1211
+ #
1212
+ # ThreadPool 线程池
1213
+ # Pool 进程池
1214
+ #
1213
1215
  # ThreadPool 共享内存, Pool 不共享内存
1214
1216
  # ThreadPool 可以解决 Pool 在某些情况下产生的 Can't pickle local object 的错误
1215
- # https://stackoverflow.com/a/58897266
1216
- try:
1217
+ # https://stackoverflow.com/a/58897266
1218
+ #
1219
+ # 如果要启动一个新的进程或者线程, 将 process_num 设置为 1 即可
1217
1220
 
1218
- # 处理数据
1219
- if len(process_data) <= process_num:
1220
- process_num = len(process_data)
1221
- _data = process_data
1222
- else:
1223
- _data = list_split(process_data, process_num, equally=True)
1221
+ try:
1224
1222
 
1225
- if _data is None:
1223
+ # 检查参数
1224
+ if not check_arguments([(process_data, list, "process_data")]):
1226
1225
  return False
1227
1226
 
1228
- # 执行函数
1229
- if isTrue(thread, bool):
1230
- # 多线程
1231
- logger.info("execute multi thread ......")
1232
- with ThreadPool(process_num, **kwargs) as p:
1233
- return p.map(process_func, _data)
1234
- else:
1235
- # 多进程
1236
- logger.info("execute multi process ......")
1237
- with Pool(process_num, **kwargs) as p:
1238
- return p.map(process_func, _data)
1227
+ # 确保并行数不超过数据量
1228
+ process_num = min(len(process_data), process_num)
1229
+ _data_chunks = (
1230
+ list_split(process_data, process_num, equally=True)
1231
+ if process_num > 1
1232
+ else [process_data]
1233
+ )
1239
1234
 
1240
- except Exception as e:
1241
- logger.exception(e)
1242
- return False
1235
+ if not _data_chunks:
1236
+ logger.error("data chunks error")
1237
+ return False
1243
1238
 
1239
+ logger.info(
1240
+ f"Starting {'multi-threading' if thread else 'multi-processing'} with {process_num} workers..."
1241
+ )
1242
+
1243
+ # 执行多线程或多进程任务
1244
+ pool_cls = ThreadPool if thread else Pool
1245
+ with pool_cls(process_num, **kwargs) as pool:
1246
+ return pool.map(process_func, _data_chunks)
1244
1247
 
1245
- def new_process(
1246
- process_func: Callable,
1247
- process_data: Any = None,
1248
- thread: bool = False,
1249
- daemon: bool = True,
1250
- **kwargs
1251
- ) -> Thread | Process | bool:
1252
- """New Process"""
1253
- try:
1254
- if isTrue(thread, bool):
1255
- process = Thread(target=process_func, args=process_data, **kwargs)
1256
- else:
1257
- process = Process(target=process_func, args=process_data, **kwargs)
1258
- process.daemon = daemon
1259
- process.start()
1260
- return process
1261
1248
  except Exception as e:
1262
1249
  logger.exception(e)
1263
1250
  return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ezKit
3
- Version: 1.10.0
3
+ Version: 1.10.1
4
4
  Summary: Easy Kit
5
5
  Author: septvean
6
6
  Author-email: septvean@gmail.com
@@ -9,10 +9,10 @@ ezKit/qywx.py,sha256=X_H4fzP-iEqeDEbumr7D1bXi6dxczaxfO8iyutzy02s,7171
9
9
  ezKit/redis.py,sha256=g2_V4jvq0djRc20jLZkgeAeF_bYrq-Rbl_kHcCUPZcA,1965
10
10
  ezKit/sendemail.py,sha256=tRXCsJm_RfTJ9xEWe_lTQ5kOs2JxHGPXvq0oWA7prq0,7263
11
11
  ezKit/token.py,sha256=HKREyZj_T2S8-aFoFIrBXTaCKExQq4zE66OHXhGHqQg,1750
12
- ezKit/utils.py,sha256=TDsL3PRkQy6NdZgphkgwacbWvHqEmq4LOkfNzmxV4DY,42682
12
+ ezKit/utils.py,sha256=k3hSnOwNSyyRDVwfEzQUXQh_oJJ51KOT-PvLFPYOtOE,42517
13
13
  ezKit/xftp.py,sha256=XyIdr_2rxRVLqPofG6fIYWhAMVsFwTyp46dg5P9FLW4,7774
14
- ezKit-1.10.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
15
- ezKit-1.10.0.dist-info/METADATA,sha256=O02PkOxx-UBmJsu2R7TIJNrTw2d4GvsLsbCgvmHmgp0,191
16
- ezKit-1.10.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
17
- ezKit-1.10.0.dist-info/top_level.txt,sha256=aYLB_1WODsqNTsTFWcKP-BN0KCTKcV-HZJ4zlHkCFw8,6
18
- ezKit-1.10.0.dist-info/RECORD,,
14
+ ezKit-1.10.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
15
+ ezKit-1.10.1.dist-info/METADATA,sha256=7-BrvzaxysoECMgvFVFeBbVHX2RgQGbdYUrZS3xumUo,191
16
+ ezKit-1.10.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
17
+ ezKit-1.10.1.dist-info/top_level.txt,sha256=aYLB_1WODsqNTsTFWcKP-BN0KCTKcV-HZJ4zlHkCFw8,6
18
+ ezKit-1.10.1.dist-info/RECORD,,
File without changes