ezKit 1.6.2__py3-none-any.whl → 1.7.0__py3-none-any.whl

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.
ezKit/utils.py CHANGED
@@ -1,17 +1,6 @@
1
1
  """
2
2
  Python Utils
3
3
  """
4
- """
5
- 函数
6
-
7
- - 明确 参数 和 返回值 的类型
8
- - 必须有返回值
9
- - 添加一个 debug 参数, 用于调试
10
- - 如果 debug 为 True, 则输出相关信息, 否则一律不输出任何信息
11
- - logger.exception(e) if v_true(debug, bool) else next
12
- - 必须有说明
13
- - 必须用 try ... except ... 包裹
14
- """
15
4
  import csv
16
5
  import datetime
17
6
  import hashlib
@@ -52,51 +41,47 @@ def v_true(
52
41
  """
53
42
  检查变量类型以及变量是否为True
54
43
  """
55
- """
56
- 常见类型:
57
-
58
- Boolean bool False
59
- Numbers int/float 0/0.0
60
- String str ""
61
- List list/tuple/set []/()/{}
62
- Dictionary dict {}
44
+ # 常见类型:
45
+ # Boolean bool False
46
+ # Numbers int/float 0/0.0
47
+ # String str ""
48
+ # List list/tuple/set []/()/{}
49
+ # Dictionary dict {}
50
+ # 函数使用 callable(func) 判断
63
51
 
64
- 函数使用 callable(func) 判断
65
- """
66
52
  try:
53
+
67
54
  if isinstance(v_instance, v_type):
68
- if true_list is not None and false_list is None and (
69
- isinstance(true_list, list) or
70
- isinstance(true_list, tuple) or
71
- isinstance(true_list, set) or
72
- isinstance(true_list, str)
55
+
56
+ if all(
57
+ true_list is not None,
58
+ false_list is None,
59
+ isinstance(true_list, (list, tuple, set, str))
73
60
  ):
74
- return True if v_instance in true_list else False
75
- elif true_list is None and false_list is not None and (
76
- isinstance(false_list, list) or
77
- isinstance(false_list, tuple) or
78
- isinstance(false_list, set) or
79
- isinstance(false_list, str)
61
+ return v_instance in true_list
62
+
63
+ if all(
64
+ true_list is None,
65
+ false_list is not None,
66
+ isinstance(false_list, (list, tuple, set, str))
80
67
  ):
81
- return True if v_instance not in false_list else False
82
- elif true_list is not None and false_list is not None and (
83
- isinstance(true_list, list) or
84
- isinstance(true_list, tuple) or
85
- isinstance(true_list, set) or
86
- isinstance(true_list, str)
87
- ) and (
88
- isinstance(false_list, list) or
89
- isinstance(false_list, tuple) or
90
- isinstance(false_list, set) or
91
- isinstance(false_list, str)
68
+ return v_instance not in false_list
69
+
70
+ if all(
71
+ true_list is not None,
72
+ false_list is not None,
73
+ isinstance(true_list, (list, tuple, set, str)),
74
+ isinstance(false_list, (list, tuple, set, str))
92
75
  ):
93
- return True if (v_instance in true_list) and (v_instance not in false_list) else False
94
- else:
95
- return True if v_instance not in [False, None, 0, 0.0, '', (), [], {*()}, {*[]}, {*{}}, {}] else False
96
- else:
97
- return False
76
+ return (v_instance in true_list) and (v_instance not in false_list)
77
+
78
+ return v_instance not in [False, None, 0, 0.0, '', (), [], {*()}, {*[]}, {*{}}, {}]
79
+
80
+ return False
81
+
98
82
  except Exception as e:
99
- logger.exception(e) if v_true(debug, bool) else next
83
+ if v_true(debug, bool):
84
+ logger.exception(e)
100
85
  return False
101
86
 
102
87
 
@@ -106,22 +91,25 @@ def os_environ(
106
91
  debug: bool = False
107
92
  ) -> any:
108
93
  """伪全局变量"""
109
- """
110
- Python 没有全局变量, 多个文件无法调用同一个变量
111
- 为了解决这个问题, 将变量设置为系统变量, 从而实现多个文件调用同一个变量
112
- """
94
+ # Python 没有全局变量, 多个文件无法调用同一个变量
95
+ # 为了解决这个问题, 将变量设置为系统变量, 从而实现多个文件调用同一个变量
113
96
  try:
97
+
114
98
  # 变量名添加一个前缀, 防止和系统中其它变量名冲突
115
99
  variable_name = f'PYTHON_VARIABLE_{name}'
116
- if value == None:
100
+
101
+ if value is None:
117
102
  data = os.environ.get(variable_name)
118
103
  return json.loads(data)
119
- else:
120
- data = json.dumps(value)
121
- os.environ[variable_name] = data
122
- return value
104
+
105
+ data = json.dumps(value)
106
+ os.environ[variable_name] = data
107
+
108
+ return value
109
+
123
110
  except Exception as e:
124
- logger.exception(e) if v_true(debug, bool) else next
111
+ if v_true(debug, bool):
112
+ logger.exception(e)
125
113
  return None
126
114
 
127
115
 
@@ -133,11 +121,10 @@ def mam_of_numbers(
133
121
  dest_type: str | None = None,
134
122
  debug: bool = False
135
123
  ) -> tuple[int | float, int | float, int | float] | tuple[None, None, None]:
136
- """
137
- 返回一组数字中的 最大值(maximum), 平均值(average), 最小值(minimum)
138
- numbers 数字列表 (仅支持 list 和 tuple, 不支 set)
139
- dest_type 目标类型 (将数字列表中的数字转换成统一的类型)
140
- """
124
+ """(maximum, average, minimum)"""
125
+ # 返回一组数字中的 最大值(maximum), 平均值(average), 最小值(minimum)
126
+ # numbers 数字列表 (仅支持 list 和 tuple, 不支 set)
127
+ # dest_type 目标类型 (将数字列表中的数字转换成统一的类型)
141
128
  try:
142
129
  _numbers = deepcopy(numbers)
143
130
  match True:
@@ -150,7 +137,8 @@ def mam_of_numbers(
150
137
  _num_min = min(_numbers)
151
138
  return _num_max, _num_avg, _num_min
152
139
  except Exception as e:
153
- logger.exception(e) if v_true(debug, bool) else next
140
+ if v_true(debug, bool):
141
+ logger.exception(e)
154
142
  return None, None, None
155
143
 
156
144
 
@@ -159,28 +147,26 @@ def step_number_for_split_equally(
159
147
  split_equally_number: int,
160
148
  debug: bool = False
161
149
  ) -> int | None:
162
- """
163
- 平分数字的步长
164
- integer 数字
165
- split_equally_number 平分 integer 的数字
166
- """
167
- """
168
- 示例:
169
-
170
- [1, 2, 3, 4, 5, 6, 7, 8, 9]
171
-
172
- 分成 2 份 -> [[1, 2, 3, 4, 5], [6, 7, 8, 9]] -> 返回 5
173
- 分成 3 份 -> [[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> 返回 3
174
- 分成 4 份 -> [[1, 2, 3], [4, 5], [6, 7], [8, 9]] -> 返回 3
175
- 分成 5 份 -> [[1, 2], [3, 4], [5, 6], [7, 8], [9]] -> 返回 2
176
- """
150
+ """step number for split equally"""
151
+ # 平分数字的步长
152
+ # integer 数字
153
+ # split_equally_number 平分 integer 的数字
154
+ #
155
+ # 示例:
156
+ #
157
+ # [1, 2, 3, 4, 5, 6, 7, 8, 9]
158
+ #
159
+ # 分成 2 份 -> [[1, 2, 3, 4, 5], [6, 7, 8, 9]] -> 返回 5
160
+ # 分成 3 份 -> [[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> 返回 3
161
+ # 分成 4 份 -> [[1, 2, 3], [4, 5], [6, 7], [8, 9]] -> 返回 3
162
+ # 分成 5 份 -> [[1, 2], [3, 4], [5, 6], [7, 8], [9]] -> 返回 2
177
163
  try:
178
164
  if integer % split_equally_number == 0:
179
165
  return int(integer / split_equally_number)
180
- else:
181
- return int(integer / split_equally_number) + 1
166
+ return int(integer / split_equally_number) + 1
182
167
  except Exception as e:
183
- logger.exception(e) if v_true(debug, bool) else next
168
+ if v_true(debug, bool):
169
+ logger.exception(e)
184
170
  return None
185
171
 
186
172
 
@@ -189,13 +175,12 @@ def division(
189
175
  divisor: int | float,
190
176
  debug: bool = False
191
177
  ) -> float | None:
192
- """
193
- 除法
194
- """
178
+ """Division"""
195
179
  try:
196
180
  return dividend / divisor
197
181
  except Exception as e:
198
- logger.exception(e) if v_true(debug, bool) else next
182
+ if v_true(debug, bool):
183
+ logger.exception(e)
199
184
  return None
200
185
 
201
186
 
@@ -203,13 +188,13 @@ def divisor_1000(
203
188
  dividend: int | float,
204
189
  debug: bool = False
205
190
  ) -> float | None:
206
- """
207
- 除法, 除以 1000
208
- """
191
+ """Division (divisor: 1000)"""
192
+ # 除法, 除以 1000
209
193
  try:
210
194
  return dividend / 1000
211
195
  except Exception as e:
212
- logger.exception(e) if v_true(debug, bool) else next
196
+ if v_true(debug, bool):
197
+ logger.exception(e)
213
198
  return None
214
199
 
215
200
 
@@ -217,13 +202,13 @@ def divisor_1024(
217
202
  dividend: int | float,
218
203
  debug: bool = False
219
204
  ) -> float | None:
220
- """
221
- 除法, 除以 1024
222
- """
205
+ """Division (divisor: 1024)"""
206
+ # 除法, 除以 1024
223
207
  try:
224
208
  return dividend / 1024
225
209
  except Exception as e:
226
- logger.exception(e) if v_true(debug, bool) else next
210
+ if v_true(debug, bool):
211
+ logger.exception(e)
227
212
  return None
228
213
 
229
214
 
@@ -231,13 +216,12 @@ def divisor_square_1000(
231
216
  dividend: int | float,
232
217
  debug: bool = False
233
218
  ) -> float | None:
234
- """
235
- 除法, 除以 1000的次方
236
- """
219
+ """Division (divisor: 1000*1000)"""
237
220
  try:
238
221
  return dividend / (1000 * 1000)
239
222
  except Exception as e:
240
- logger.exception(e) if v_true(debug, bool) else next
223
+ if v_true(debug, bool):
224
+ logger.exception(e)
241
225
  return None
242
226
 
243
227
 
@@ -245,13 +229,12 @@ def divisor_square_1024(
245
229
  dividend: int | float,
246
230
  debug: bool = False
247
231
  ) -> float | None:
248
- """
249
- 除法, 除以 1024的次方
250
- """
232
+ """Division (divisor: 1024*1024)"""
251
233
  try:
252
234
  return dividend / (1024 * 1024)
253
235
  except Exception as e:
254
- logger.exception(e) if v_true(debug, bool) else next
236
+ if v_true(debug, bool):
237
+ logger.exception(e)
255
238
  return None
256
239
 
257
240
 
@@ -263,11 +246,10 @@ def check_file_type(
263
246
  file_type: str,
264
247
  debug: bool = False
265
248
  ) -> bool | None:
266
- """
267
- 检查文件类型
268
- file_object 文件对象
269
- file_type 文件类型
270
- """
249
+ """check file type"""
250
+ # 检查文件类型
251
+ # file_object 文件对象
252
+ # file_type 文件类型
271
253
  try:
272
254
  _file_path = Path(file_object)
273
255
  match True:
@@ -296,7 +278,8 @@ def check_file_type(
296
278
  case _:
297
279
  return False
298
280
  except Exception as e:
299
- logger.exception(e) if v_true(debug, bool) else next
281
+ if v_true(debug, bool):
282
+ logger.exception(e)
300
283
  return False
301
284
 
302
285
 
@@ -309,14 +292,11 @@ def list_sort(
309
292
  debug: bool = False,
310
293
  **kwargs
311
294
  ) -> list | None:
312
- """
313
- 列表排序, 示例: list_sort(['1.2.3.4', '2.3.4.5'], key=inet_aton)
314
- """
315
- """
316
- 参考文档:
317
- https://stackoverflow.com/a/4183538
318
- https://blog.csdn.net/u013541325/article/details/117530957
319
- """
295
+ """list sort"""
296
+ # 列表排序, 示例: list_sort(['1.2.3.4', '2.3.4.5'], key=inet_aton)
297
+ # 参考文档:
298
+ # https://stackoverflow.com/a/4183538
299
+ # https://blog.csdn.net/u013541325/article/details/117530957
320
300
  try:
321
301
 
322
302
  # from ipaddress import ip_address
@@ -331,7 +311,8 @@ def list_sort(
331
311
  return _data
332
312
 
333
313
  except Exception as e:
334
- logger.exception(e) if v_true(debug, bool) else next
314
+ if v_true(debug, bool):
315
+ logger.exception(e)
335
316
  return None
336
317
 
337
318
 
@@ -341,18 +322,15 @@ def list_dict_sorted_by_key(
341
322
  debug: bool = False,
342
323
  **kwargs
343
324
  ) -> list | None:
344
- """
345
- 列表字典排序
346
- """
347
- """
348
- 参考文档:
349
- https://stackoverflow.com/a/73050
350
- """
325
+ """list dict sorted by key"""
326
+ # 列表字典排序
327
+ # 参考文档: https://stackoverflow.com/a/73050
351
328
  try:
352
329
  _data = deepcopy(data)
353
330
  return sorted(_data, key=lambda x: x[key], **kwargs)
354
331
  except Exception as e:
355
- logger.exception(e) if v_true(debug, bool) else next
332
+ if v_true(debug, bool):
333
+ logger.exception(e)
356
334
  return None
357
335
 
358
336
 
@@ -362,33 +340,32 @@ def list_split(
362
340
  equally: bool = False,
363
341
  debug: bool = False
364
342
  ) -> list | None:
365
- """
366
- 列表分割
367
- """
368
- """
369
- 默认: 将 list 以 number个元素为一个list 分割
370
-
371
- data = [1, 2, 3, 4, 5, 6, 7]
343
+ """list split"""
344
+ # 列表分割
345
+ #
346
+ # 默认: 将 list 以 number个元素为一个list 分割
347
+ #
348
+ # data = [1, 2, 3, 4, 5, 6, 7]
349
+ #
350
+ # list_split(data, 2) -> 将 data 以 2个元素为一个 list 分割
351
+ # [[1, 2], [3, 4], [5, 6], [7]]
352
+ #
353
+ # list_split(data, 3) -> 将 data 以 3个元素为一个 list 分割
354
+ # [[1, 2, 3], [4, 5, 6], [7]]
355
+ #
356
+ # equally 为 True 时, 将 data 平均分成 number 份
357
+ #
358
+ # data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
359
+ #
360
+ # list_split_equally(data, 5) -> 将 data 平均分成 5 份
361
+ # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16], [17, 18, 19]]
362
+ #
363
+ # list_split_equally(data, 6) -> 将 data 平均分成 6 份
364
+ # [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10], [11, 12, 13], [14, 15, 16], [17, 18, 19]]
365
+ #
366
+ # list_split_equally(data, 7) -> 将 data 平均分成 7 份
367
+ # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17], [18, 19]]
372
368
 
373
- list_split(data, 2) -> 将 data 以 2个元素为一个 list 分割
374
- [[1, 2], [3, 4], [5, 6], [7]]
375
-
376
- list_split(data, 3) -> 将 data 以 3个元素为一个 list 分割
377
- [[1, 2, 3], [4, 5, 6], [7]]
378
-
379
- equally 为 True 时, 将 data 平均分成 number 份
380
-
381
- data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
382
-
383
- list_split_equally(data, 5) -> 将 data 平均分成 5 份
384
- [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16], [17, 18, 19]]
385
-
386
- list_split_equally(data, 6) -> 将 data 平均分成 6 份
387
- [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10], [11, 12, 13], [14, 15, 16], [17, 18, 19]]
388
-
389
- list_split_equally(data, 7) -> 将 data 平均分成 7 份
390
- [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17], [18, 19]]
391
- """
392
369
  try:
393
370
 
394
371
  # 数据拷贝
@@ -403,29 +380,46 @@ def list_split(
403
380
  logger.info(f"data length: {_data_length}")
404
381
 
405
382
  if _data_length < number:
406
- logger.error('number must greater than data length') if v_true(debug, bool) else next
383
+ if v_true(debug, bool):
384
+ logger.error('number must greater than data length')
407
385
  return None
408
- elif _data_length == number:
386
+
387
+ if _data_length == number:
388
+
409
389
  _data_result = [[i] for i in _data_object]
390
+
410
391
  else:
411
392
 
412
393
  if equally is True:
413
394
 
414
395
  # 数据平分时, 每份数据的最大长度
415
396
  _step_number = step_number_for_split_equally(_data_length, number, debug=debug)
416
- logger.info(f"step number: {_step_number}") if v_true(debug, bool) else next
397
+
398
+ if v_true(debug, bool):
399
+ logger.info(f"step number: {_step_number}")
400
+
417
401
  if _data_length % number == 0:
402
+
418
403
  index_number_list = list(range(0, _data_length, number))
419
- logger.info(f"index number list: {index_number_list}") if v_true(debug, bool) else next
404
+
405
+ if v_true(debug, bool):
406
+ logger.info(f"index number list: {index_number_list}")
407
+
420
408
  for index_number in index_number_list:
421
- logger.info(f"index: {index_number}, data: {_data_object[index_number:index_number + number]}") if v_true(debug, bool) else next
409
+
410
+ if v_true(debug, bool):
411
+ logger.info(f"index: {index_number}, data: {_data_object[index_number:index_number + number]}")
412
+
422
413
  _data_result.append(deepcopy(_data_object[index_number:index_number + number]))
414
+
423
415
  else:
416
+
424
417
  # 前一部分
425
418
  previous_end_number = (_data_length % number) * _step_number
426
419
  previous_index_number_list = list(range(0, previous_end_number, _step_number))
427
420
  for index_number in previous_index_number_list:
428
421
  _data_result.append(deepcopy(_data_object[index_number:index_number + _step_number]))
422
+
429
423
  # 后一部分
430
424
  next_number_list = list(range(previous_end_number, _data_length, _step_number - 1))
431
425
  for index_number in next_number_list:
@@ -439,7 +433,8 @@ def list_split(
439
433
  return _data_result
440
434
 
441
435
  except Exception as e:
442
- logger.exception(e) if v_true(debug, bool) else next
436
+ if v_true(debug, bool):
437
+ logger.exception(e)
443
438
  return None
444
439
 
445
440
 
@@ -449,16 +444,16 @@ def list_print_by_step(
449
444
  separator: str | None = None,
450
445
  debug: bool = False
451
446
  ) -> bool:
452
- """
453
- 列表按照 步长 和 分隔符 有规律的输出
454
- """
447
+ """list print by step"""
448
+ # 列表按照 步长 和 分隔符 有规律的输出
455
449
  try:
456
450
  _data_list = list_split(data, number, debug=debug)
457
451
  for _item in _data_list:
458
452
  print(*_item, sep=separator)
459
453
  return True
460
454
  except Exception as e:
461
- logger.exception(e) if v_true(debug, bool) else next
455
+ if v_true(debug, bool):
456
+ logger.exception(e)
462
457
  return False
463
458
 
464
459
 
@@ -467,12 +462,14 @@ def list_remove_list(
467
462
  remove: list,
468
463
  debug: bool = False
469
464
  ) -> list | None:
465
+ """List remove List"""
470
466
  try:
471
467
  _original = deepcopy(original)
472
468
  _remove = deepcopy(remove)
473
469
  return [i for i in _original if i not in _remove]
474
470
  except Exception as e:
475
- logger.exception(e) if v_true(debug, bool) else next
471
+ if v_true(debug, bool):
472
+ logger.exception(e)
476
473
  return None
477
474
 
478
475
 
@@ -480,14 +477,16 @@ def list_merge(
480
477
  data: list,
481
478
  debug: bool = False
482
479
  ) -> list | None:
483
- """合并 List 中的 List 为一个 List"""
480
+ """list merge"""
481
+ # 合并 List 中的 List 为一个 List
484
482
  try:
485
483
  _results = []
486
484
  for i in deepcopy(data):
487
485
  _results += i
488
486
  return _results
489
487
  except Exception as e:
490
- logger.exception(e) if v_true(debug, bool) else next
488
+ if v_true(debug, bool):
489
+ logger.exception(e)
491
490
  return None
492
491
 
493
492
 
@@ -497,13 +496,15 @@ def list_to_file(
497
496
  encoding: str = 'utf-8-sig',
498
497
  debug: bool = False
499
498
  ) -> bool:
499
+ """list to file"""
500
500
  try:
501
501
  with open(file, 'w', encoding=encoding) as _file:
502
502
  for line in data:
503
503
  _file.write(f"{line}\n")
504
504
  return True
505
505
  except Exception as e:
506
- logger.exception(e) if v_true(debug, bool) else next
506
+ if v_true(debug, bool):
507
+ logger.exception(e)
507
508
  return False
508
509
 
509
510
  def list_to_csvfile(
@@ -514,6 +515,7 @@ def list_to_csvfile(
514
515
  debug: bool = False,
515
516
  **kwargs
516
517
  ) -> bool:
518
+ """list to csvfile"""
517
519
  try:
518
520
  with open(file, 'w', encoding=encoding) as _file:
519
521
  # CRLF replaced by LF
@@ -524,7 +526,8 @@ def list_to_csvfile(
524
526
  outcsv.writerows(data)
525
527
  return True
526
528
  except Exception as e:
527
- logger.exception(e) if v_true(debug, bool) else next
529
+ if v_true(debug, bool):
530
+ logger.exception(e)
528
531
  return False
529
532
 
530
533
  def range_zfill(
@@ -534,7 +537,8 @@ def range_zfill(
534
537
  width: int,
535
538
  debug: bool = False
536
539
  ) -> list | None:
537
- """生成长度相同的字符串的列表"""
540
+ """range zfill"""
541
+ # 生成长度相同的字符串的列表
538
542
  # 示例: range_zfill(8, 13, 1, 2) => ['08', '09', '10', '11', '12']
539
543
  # 生成 小时 列表: range_zfill(0, 24, 1, 2)
540
544
  # 生成 分钟和秒 列表: range_zfill(0, 60, 1, 2)
@@ -543,7 +547,8 @@ def range_zfill(
543
547
  try:
544
548
  return [str(i).zfill(width) for i in range(start, stop, step)]
545
549
  except Exception as e:
546
- logger.exception(e) if v_true(debug, bool) else next
550
+ if v_true(debug, bool):
551
+ logger.exception(e)
547
552
  return None
548
553
 
549
554
 
@@ -555,12 +560,14 @@ def dict_remove_key(
555
560
  key: str,
556
561
  debug: bool = False
557
562
  ) -> None | dict:
563
+ """dict remove key"""
558
564
  try:
559
565
  data_copy: dict = deepcopy(data)
560
566
  data_copy.pop(key)
561
567
  return data_copy
562
568
  except Exception as e:
563
- logger.exception(e) if v_true(debug, bool) else next
569
+ if v_true(debug, bool):
570
+ logger.exception(e)
564
571
  return None
565
572
 
566
573
  def dict_to_file(
@@ -570,12 +577,14 @@ def dict_to_file(
570
577
  debug: bool = False,
571
578
  **kwargs
572
579
  ) -> bool:
580
+ """dict to file"""
573
581
  try:
574
582
  with open(file, 'w', encoding=encoding) as _file:
575
583
  json.dump(obj=data, fp=_file, indent=4, sort_keys=True, **kwargs)
576
584
  return True
577
585
  except Exception as e:
578
- logger.exception(e) if v_true(debug, bool) else next
586
+ if v_true(debug, bool):
587
+ logger.exception(e)
579
588
  return False
580
589
 
581
590
 
@@ -585,10 +594,9 @@ def dict_nested_update(
585
594
  value: any,
586
595
  debug: bool = False
587
596
  ) -> bool:
588
- """
589
- dictionary nested update
590
- https://stackoverflow.com/a/58885744
591
- """
597
+ """dict nested update"""
598
+ # dictionary nested update
599
+ # https://stackoverflow.com/a/58885744
592
600
  try:
593
601
  if v_true(data, dict, debug=debug):
594
602
  for _k, _v in data.items():
@@ -610,7 +618,8 @@ def dict_nested_update(
610
618
  return False
611
619
  return True
612
620
  except Exception as e:
613
- logger.exception(e) if v_true(debug, bool) else next
621
+ if v_true(debug, bool):
622
+ logger.exception(e)
614
623
  return False
615
624
 
616
625
 
@@ -622,23 +631,32 @@ def filename(
622
631
  split: str = '.',
623
632
  debug: bool = False
624
633
  ) -> str | None:
625
- """获取文件名称"""
626
- '''
627
- https://stackoverflow.com/questions/678236/how-do-i-get-the-filename-without-the-extension-from-a-path-in-python
628
- https://stackoverflow.com/questions/4152963/get-name-of-current-script-in-python
629
- '''
634
+ """filename"""
635
+ # 获取文件名称
636
+ # https://stackoverflow.com/questions/678236/how-do-i-get-the-filename-without-the-extension-from-a-path-in-python
637
+ # https://stackoverflow.com/questions/4152963/get-name-of-current-script-in-python
630
638
  try:
639
+
631
640
  if v_true(debug, bool):
632
641
  logger.info(f"file: {file}")
633
642
  logger.info(f"split: {split}")
643
+
634
644
  _basename = str(os.path.basename(file))
635
- logger.info(f"basename: {_basename}") if v_true(debug, bool) else next
645
+
646
+ if v_true(debug, bool):
647
+ logger.info(f"basename: {_basename}")
648
+
636
649
  _index_of_split = _basename.index(split)
637
- logger.info(f"index of split: {_index_of_split}") if v_true(debug, bool) else next
638
- logger.info(f"filename: {_basename[:_index_of_split]}") if v_true(debug, bool) else next
650
+
651
+ if v_true(debug, bool):
652
+ logger.info(f"index of split: {_index_of_split}")
653
+ logger.info(f"filename: {_basename[:_index_of_split]}")
654
+
639
655
  return _basename[:_index_of_split]
656
+
640
657
  except Exception as e:
641
- logger.exception(e) if v_true(debug, bool) else next
658
+ if v_true(debug, bool):
659
+ logger.exception(e)
642
660
  return None
643
661
 
644
662
 
@@ -647,12 +665,11 @@ def filehash(
647
665
  sha: str = 'md5',
648
666
  debug: bool = False
649
667
  ) -> str | None:
650
- """获取文件Hash"""
651
- """
652
- 参考文档:
653
- https://stackoverflow.com/a/59056837
654
- https://stackoverflow.com/questions/22058048/hashing-a-file-in-python
655
- """
668
+ """filehash"""
669
+ # 获取文件Hash
670
+ # 参考文档:
671
+ # https://stackoverflow.com/a/59056837
672
+ # https://stackoverflow.com/questions/22058048/hashing-a-file-in-python
656
673
  try:
657
674
  with open(file, "rb") as _file:
658
675
  match True:
@@ -687,7 +704,8 @@ def filehash(
687
704
  file_hash.update(chunk)
688
705
  return file_hash.hexdigest()
689
706
  except Exception as e:
690
- logger.exception(e) if v_true(debug, bool) else next
707
+ if v_true(debug, bool):
708
+ logger.exception(e)
691
709
  return None
692
710
 
693
711
 
@@ -695,11 +713,13 @@ def filesize(
695
713
  file: str,
696
714
  debug: bool = False
697
715
  ) -> int | None:
698
- """获取文件大小"""
716
+ """filesize"""
717
+ # 获取文件大小
699
718
  try:
700
719
  return os.path.getsize(file)
701
720
  except Exception as e:
702
- logger.exception(e) if v_true(debug, bool) else next
721
+ if v_true(debug, bool):
722
+ logger.exception(e)
703
723
  return None
704
724
 
705
725
 
@@ -707,7 +727,8 @@ def filesize(
707
727
 
708
728
 
709
729
  def resolve_path() -> str | None:
710
- """获取当前目录名称"""
730
+ """resolve path"""
731
+ # 获取当前目录名称
711
732
  return str(Path().resolve())
712
733
 
713
734
 
@@ -720,7 +741,8 @@ def parent_path(
720
741
  try:
721
742
  return str(Path(path, **kwargs).parent.resolve()) if v_true(path, str, debug=debug) else None
722
743
  except Exception as e:
723
- logger.exception(e) if v_true(debug, bool) else next
744
+ if v_true(debug, bool):
745
+ logger.exception(e)
724
746
  return None
725
747
 
726
748
 
@@ -731,10 +753,12 @@ def real_path(
731
753
  ) -> str | None:
732
754
  """获取真实路径"""
733
755
  try:
734
- logger.info(f"path: {path}") if v_true(debug, bool) else next
756
+ if v_true(debug, bool):
757
+ logger.info(f"path: {path}")
735
758
  return os.path.realpath(path, **kwargs)
736
759
  except Exception as e:
737
- logger.exception(e) if v_true(debug, bool) else next
760
+ if v_true(debug, bool):
761
+ logger.exception(e)
738
762
  return None
739
763
 
740
764
 
@@ -748,10 +772,8 @@ def retry(
748
772
  **kwargs
749
773
  ):
750
774
  """重试"""
751
- """
752
- 函数传递参数: https://stackoverflow.com/a/803632
753
- callable() 判断类型是非为函数: https://stackoverflow.com/a/624939
754
- """
775
+ # 函数传递参数: https://stackoverflow.com/a/803632
776
+ # callable() 判断类型是非为函数: https://stackoverflow.com/a/624939
755
777
  try:
756
778
  _num = 0
757
779
  while True:
@@ -764,61 +786,60 @@ def retry(
764
786
  try:
765
787
  return func(**kwargs)
766
788
  except Exception as e:
767
- logger.exception(e) if v_true(debug, bool) else next
789
+ if v_true(debug, bool):
790
+ logger.exception(e)
768
791
  logger.success('retrying ...')
769
792
  continue
770
793
  # break
771
794
  except Exception as e:
772
- logger.exception(e) if v_true(debug, bool) else next
795
+ if v_true(debug, bool):
796
+ logger.exception(e)
773
797
 
774
798
 
775
799
  # --------------------------------------------------------------------------------------------------
776
800
 
777
-
778
- """
779
- 日期时间有两种: UTC datetime (UTC时区日期时间) 和 Local datetime (当前时区日期时间)
780
-
781
- Unix Timestamp 仅为 UTC datetime 的值
782
-
783
- 但是, Local datetime 可以直接转换为 Unix Timestamp, UTC datetime 需要先转换到 UTC TimeZone 再转换为 Unix Timestamp
784
-
785
- 相反, Unix Timestamp 可以直接转换为 UTC datetime, 要获得 Local datetime, 需要再将 UTC datetime 转换为 Local datetime
786
-
787
- https://stackoverflow.com/a/13287083
788
- https://stackoverflow.com/a/466376
789
- https://stackoverflow.com/a/7999977
790
- https://stackoverflow.com/a/3682808
791
- https://stackoverflow.com/a/63920772
792
- https://www.geeksforgeeks.org/how-to-remove-timezone-information-from-datetime-object-in-python/
793
-
794
- pytz all timezones
795
-
796
- https://stackoverflow.com/a/13867319
797
- https://stackoverflow.com/a/15692958
798
-
799
- import pytz
800
- pytz.all_timezones
801
- pytz.common_timezones
802
- pytz.timezone('US/Eastern')
803
-
804
- timezone
805
-
806
- https://stackoverflow.com/a/39079819
807
- https://stackoverflow.com/a/1681600
808
- https://stackoverflow.com/a/4771733
809
- https://stackoverflow.com/a/63920772
810
- https://toutiao.io/posts/sin4x0/preview
811
-
812
- 其它:
813
-
814
- dt.replace(tzinfo=timezone.utc).astimezone(tz=None)
815
-
816
- (dt.replace(tzinfo=timezone.utc).astimezone(tz=None)).strftime(format)
817
- datetime.fromisoformat((dt.replace(tzinfo=timezone.utc).astimezone(tz=None)).strftime(format))
818
- string_to_datetime((dt.replace(tzinfo=timezone.utc).astimezone(tz=None)).strftime(format), format)
819
-
820
- datetime.fromisoformat(time.strftime(format, time.gmtime(dt)))
821
- """
801
+ # 日期时间有两种: UTC datetime (UTC时区日期时间) 和 Local datetime (当前时区日期时间)
802
+ #
803
+ # Unix Timestamp 仅为 UTC datetime 的值
804
+ #
805
+ # 但是, Local datetime 可以直接转换为 Unix Timestamp, UTC datetime 需要先转换到 UTC TimeZone 再转换为 Unix Timestamp
806
+ #
807
+ # 相反, Unix Timestamp 可以直接转换为 UTC datetime, 要获得 Local datetime, 需要再将 UTC datetime 转换为 Local datetime
808
+ #
809
+ # https://stackoverflow.com/a/13287083
810
+ # https://stackoverflow.com/a/466376
811
+ # https://stackoverflow.com/a/7999977
812
+ # https://stackoverflow.com/a/3682808
813
+ # https://stackoverflow.com/a/63920772
814
+ # https://www.geeksforgeeks.org/how-to-remove-timezone-information-from-datetime-object-in-python/
815
+ #
816
+ # pytz all timezones
817
+ #
818
+ # https://stackoverflow.com/a/13867319
819
+ # https://stackoverflow.com/a/15692958
820
+ #
821
+ # import pytz
822
+ # pytz.all_timezones
823
+ # pytz.common_timezones
824
+ # pytz.timezone('US/Eastern')
825
+ #
826
+ # timezone
827
+ #
828
+ # https://stackoverflow.com/a/39079819
829
+ # https://stackoverflow.com/a/1681600
830
+ # https://stackoverflow.com/a/4771733
831
+ # https://stackoverflow.com/a/63920772
832
+ # https://toutiao.io/posts/sin4x0/preview
833
+ #
834
+ # 其它:
835
+ #
836
+ # dt.replace(tzinfo=timezone.utc).astimezone(tz=None)
837
+ #
838
+ # (dt.replace(tzinfo=timezone.utc).astimezone(tz=None)).strftime(format)
839
+ # datetime.fromisoformat((dt.replace(tzinfo=timezone.utc).astimezone(tz=None)).strftime(format))
840
+ # string_to_datetime((dt.replace(tzinfo=timezone.utc).astimezone(tz=None)).strftime(format), format)
841
+ #
842
+ # datetime.fromisoformat(time.strftime(format, time.gmtime(dt)))
822
843
 
823
844
 
824
845
  def date_to_datetime(
@@ -830,20 +851,22 @@ def date_to_datetime(
830
851
  try:
831
852
  return datetime.datetime.combine(date_object, datetime.datetime.min.time())
832
853
  except Exception as e:
833
- logger.exception(e) if v_true(debug, bool) else next
854
+ if v_true(debug, bool):
855
+ logger.exception(e)
834
856
  return None
835
857
 
836
858
 
837
859
  def datetime_to_date(
838
- datetime_object: datetime.datetime,
860
+ datetime_instance: datetime.datetime,
839
861
  debug: bool = False
840
862
  ) -> datetime.date | None:
841
863
  """'日期时间'转换为'日期'"""
842
864
  # https://stackoverflow.com/a/3743240
843
865
  try:
844
- return datetime_object.date()
866
+ return datetime_instance.date()
845
867
  except Exception as e:
846
- logger.exception(e) if v_true(debug, bool) else next
868
+ if v_true(debug, bool):
869
+ logger.exception(e)
847
870
  return None
848
871
 
849
872
 
@@ -861,12 +884,13 @@ def datetime_now(
861
884
  try:
862
885
  return datetime.datetime.utcnow() if _utc is True else datetime.datetime.now(**kwargs)
863
886
  except Exception as e:
864
- logger.exception(e) if v_true(debug, bool) else next
887
+ if v_true(debug, bool):
888
+ logger.exception(e)
865
889
  return None
866
890
 
867
891
 
868
892
  def datetime_offset(
869
- datetime_object: datetime.datetime,
893
+ datetime_instance: datetime.datetime,
870
894
  debug: bool = False,
871
895
  **kwargs
872
896
  ) -> datetime.datetime | None:
@@ -877,30 +901,31 @@ def datetime_offset(
877
901
  """
878
902
  _utc = kwargs.pop("utc", False)
879
903
  try:
880
- if isinstance(datetime_object, datetime.datetime):
881
- return datetime_object + datetime.timedelta(**kwargs)
882
- else:
883
- return datetime.datetime.utcnow() + datetime.timedelta(**kwargs) if _utc is True else datetime.datetime.now() + datetime.timedelta(**kwargs)
904
+ if isinstance(datetime_instance, datetime.datetime):
905
+ return datetime_instance + datetime.timedelta(**kwargs)
906
+ return datetime.datetime.utcnow() + datetime.timedelta(**kwargs) if _utc is True else datetime.datetime.now() + datetime.timedelta(**kwargs)
884
907
  except Exception as e:
885
- logger.exception(e) if v_true(debug, bool) else next
908
+ if v_true(debug, bool):
909
+ logger.exception(e)
886
910
  return None
887
911
 
888
912
 
889
913
  def datetime_to_string(
890
- datetime_object: datetime.datetime,
914
+ datetime_instance: datetime.datetime,
891
915
  string_format: str = '%Y-%m-%d %H:%M:%S',
892
916
  debug: bool = False
893
917
  ) -> str | None:
894
918
  """'日期时间'转换为'字符串'"""
895
919
  try:
896
- return datetime.datetime.strftime(datetime_object, string_format) if isinstance(datetime_object, datetime.datetime) is True else None
920
+ return datetime.datetime.strftime(datetime_instance, string_format) if isinstance(datetime_instance, datetime.datetime) is True else None
897
921
  except Exception as e:
898
- logger.exception(e) if v_true(debug, bool) else next
922
+ if v_true(debug, bool):
923
+ logger.exception(e)
899
924
  return None
900
925
 
901
926
 
902
927
  def datetime_to_timestamp(
903
- datetime_object: datetime.datetime,
928
+ datetime_instance: datetime.datetime,
904
929
  utc: bool = False,
905
930
  debug: bool = False
906
931
  ) -> int | None:
@@ -910,17 +935,17 @@ def datetime_to_timestamp(
910
935
  UTC datetime 需要先替换 timezone 再转换为 Unix Timestamp
911
936
  """
912
937
  try:
913
- if isinstance(datetime_object, datetime.datetime):
914
- return int(datetime_object.replace(tzinfo=datetime.timezone.utc).timestamp()) if utc is True else int(datetime_object.timestamp())
915
- else:
916
- return None
938
+ if isinstance(datetime_instance, datetime.datetime):
939
+ return int(datetime_instance.replace(tzinfo=datetime.timezone.utc).timestamp()) if utc is True else int(datetime_instance.timestamp())
940
+ return None
917
941
  except Exception as e:
918
- logger.exception(e) if v_true(debug, bool) else next
942
+ if v_true(debug, bool):
943
+ logger.exception(e)
919
944
  return None
920
945
 
921
946
 
922
947
  def datetime_local_to_timezone(
923
- datetime_object: datetime.datetime,
948
+ datetime_instance: datetime.datetime,
924
949
  tz: datetime.timezone = datetime.timezone.utc,
925
950
  debug: bool = False
926
951
  ) -> datetime.datetime | None:
@@ -929,17 +954,18 @@ def datetime_local_to_timezone(
929
954
  replace(tzinfo=None) 移除结尾的时区信息
930
955
  """
931
956
  try:
932
- if isinstance(datetime_object, datetime.datetime) is True:
933
- return (datetime.datetime.fromtimestamp(datetime_object.timestamp(), tz=tz)).replace(tzinfo=None)
957
+ if isinstance(datetime_instance, datetime.datetime) is True:
958
+ return (datetime.datetime.fromtimestamp(datetime_instance.timestamp(), tz=tz)).replace(tzinfo=None)
934
959
  else:
935
960
  return None
936
961
  except Exception as e:
937
- logger.exception(e) if v_true(debug, bool) else next
962
+ if v_true(debug, bool):
963
+ logger.exception(e)
938
964
  return None
939
965
 
940
966
 
941
967
  def datetime_utc_to_timezone(
942
- datetime_object: datetime.datetime,
968
+ datetime_instance: datetime.datetime,
943
969
  tz: datetime.timezone = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo,
944
970
  debug: bool = False
945
971
  ) -> datetime.datetime | None:
@@ -948,12 +974,13 @@ def datetime_utc_to_timezone(
948
974
  replace(tzinfo=None) 移除结尾的时区信息
949
975
  """
950
976
  try:
951
- if isinstance(datetime_object, datetime.datetime) is True:
952
- return datetime_object.replace(tzinfo=datetime.timezone.utc).astimezone(tz).replace(tzinfo=None)
977
+ if isinstance(datetime_instance, datetime.datetime) is True:
978
+ return datetime_instance.replace(tzinfo=datetime.timezone.utc).astimezone(tz).replace(tzinfo=None)
953
979
  else:
954
980
  return None
955
981
  except Exception as e:
956
- logger.exception(e) if v_true(debug, bool) else next
982
+ if v_true(debug, bool):
983
+ logger.exception(e)
957
984
  return None
958
985
 
959
986
 
@@ -966,7 +993,8 @@ def timestamp_to_datetime(
966
993
  try:
967
994
  return (datetime.datetime.fromtimestamp(timestamp, tz=tz)).replace(tzinfo=None) if v_true(timestamp, int, debug=debug) else None
968
995
  except Exception as e:
969
- logger.exception(e) if v_true(debug, bool) else next
996
+ if v_true(debug, bool):
997
+ logger.exception(e)
970
998
  return None
971
999
 
972
1000
 
@@ -975,10 +1003,12 @@ def datetime_string_to_datetime(
975
1003
  datetime_format: str = '%Y-%m-%d %H:%M:%S',
976
1004
  debug: bool = False
977
1005
  ) -> datetime.datetime | None:
1006
+ """datetime string to datetime"""
978
1007
  try:
979
1008
  return datetime.datetime.strptime(datetime_string, datetime_format) if v_true(datetime_string, str, debug=debug) else None
980
1009
  except Exception as e:
981
- logger.exception(e) if v_true(debug, bool) else next
1010
+ if v_true(debug, bool):
1011
+ logger.exception(e)
982
1012
  return None
983
1013
 
984
1014
 
@@ -987,10 +1017,12 @@ def datetime_string_to_timestamp(
987
1017
  datetime_format: str = '%Y-%m-%d %H:%M:%S',
988
1018
  debug: bool = False
989
1019
  ) -> int | None:
1020
+ """datetime string to timestamp"""
990
1021
  try:
991
1022
  return int(time.mktime(time.strptime(datetime_string, datetime_format))) if v_true(datetime_string, str, debug=debug) else None
992
1023
  except Exception as e:
993
- logger.exception(e) if v_true(debug, bool) else next
1024
+ if v_true(debug, bool):
1025
+ logger.exception(e)
994
1026
  return None
995
1027
 
996
1028
 
@@ -998,6 +1030,7 @@ def datetime_object(
998
1030
  date_time: datetime.datetime,
999
1031
  debug: bool = False
1000
1032
  ) -> dict | None:
1033
+ """datetime object"""
1001
1034
  try:
1002
1035
  return {
1003
1036
  'date': date_time.strftime("%Y-%m-%d"),
@@ -1008,31 +1041,30 @@ def datetime_object(
1008
1041
  'datetime_zero': date_time.strftime('%Y-%m-%d 00:00:00')
1009
1042
  }
1010
1043
  except Exception as e:
1011
- logger.exception(e) if v_true(debug, bool) else next
1044
+ if v_true(debug, bool):
1045
+ logger.exception(e)
1012
1046
  return None
1013
1047
 
1014
1048
 
1015
1049
  # --------------------------------------------------------------------------------------------------
1016
1050
 
1017
1051
 
1018
- '''
1019
- run_cmd = bash('echo ok', universal_newlines=True, stdout=PIPE)
1020
-
1021
- if run_cmd != None:
1022
- returncode = run_cmd.returncode
1023
- outputs = run_cmd.stdout.splitlines()
1024
- print(returncode, type(returncode))
1025
- print(outputs, type(outputs))
1026
-
1027
- # echo 'echo ok' > /tmp/ok.sh
1028
- run_script = bash('/tmp/ok.sh', file=True, universal_newlines=True, stdout=PIPE)
1029
-
1030
- if run_script != None:
1031
- returncode = run_script.returncode
1032
- outputs = run_script.stdout.splitlines()
1033
- print(returncode, type(returncode))
1034
- print(outputs, type(outputs))
1035
- '''
1052
+ # run_cmd = bash('echo ok', universal_newlines=True, stdout=PIPE)
1053
+ #
1054
+ # if run_cmd != None:
1055
+ # returncode = run_cmd.returncode
1056
+ # outputs = run_cmd.stdout.splitlines()
1057
+ # print(returncode, type(returncode))
1058
+ # print(outputs, type(outputs))
1059
+ #
1060
+ # # echo 'echo ok' > /tmp/ok.sh
1061
+ # run_script = bash('/tmp/ok.sh', file=True, universal_newlines=True, stdout=PIPE)
1062
+ #
1063
+ # if run_script != None:
1064
+ # returncode = run_script.returncode
1065
+ # outputs = run_script.stdout.splitlines()
1066
+ # print(returncode, type(returncode))
1067
+ # print(outputs, type(outputs))
1036
1068
 
1037
1069
 
1038
1070
  def shell(
@@ -1050,18 +1082,17 @@ def shell(
1050
1082
  return None
1051
1083
  case True if v_true(sh_shell, str, debug=debug) and v_true(command, str, debug=debug):
1052
1084
  if isfile is True:
1053
- if sh_option == None:
1054
- return subprocess.run([sh_shell, command], **kwargs)
1055
- else:
1056
- return subprocess.run([sh_shell, sh_option, command], **kwargs)
1057
- else:
1058
- if sh_option == None:
1059
- sh_option = '-c'
1060
- return subprocess.run([sh_shell, sh_option, command], **kwargs)
1085
+ if sh_option is None:
1086
+ return subprocess.run([sh_shell, command], **kwargs, check=False)
1087
+ return subprocess.run([sh_shell, sh_option, command], **kwargs, check=False)
1088
+ if sh_option is None:
1089
+ sh_option = '-c'
1090
+ return subprocess.run([sh_shell, sh_option, command], **kwargs, check=False)
1061
1091
  case _:
1062
1092
  return None
1063
1093
  except Exception as e:
1064
- logger.exception(e) if v_true(debug, bool) else next
1094
+ if v_true(debug, bool):
1095
+ logger.exception(e)
1065
1096
  return None
1066
1097
 
1067
1098
 
@@ -1072,39 +1103,37 @@ def json_file_parser(
1072
1103
  file: str,
1073
1104
  debug: bool = False
1074
1105
  ) -> dict | None:
1106
+ """JSON File Parser"""
1075
1107
  try:
1076
1108
  if check_file_type(file, 'file', debug=debug):
1077
- with open(file) as json_raw:
1109
+ with open(file, encoding="utf-8") as json_raw:
1078
1110
  json_dict = json.load(json_raw)
1079
1111
  return json_dict
1080
- else:
1081
- logger.error(f"No such file: {file}") if v_true(debug, bool) else next
1082
- return None
1112
+ if v_true(debug, bool):
1113
+ logger.error(f"No such file: {file}")
1114
+ return None
1083
1115
  except Exception as e:
1084
- logger.exception(e) if v_true(debug, bool) else next
1116
+ if v_true(debug, bool):
1117
+ logger.exception(e)
1085
1118
  return None
1086
1119
 
1087
-
1088
- """
1089
- json_raw = '''
1090
- {
1091
- "markdown.preview.fontSize": 14,
1092
- "editor.minimap.enabled": false,
1093
- "workbench.iconTheme": "vscode-icons",
1094
- "http.proxy": "http://127.0.0.1:1087"
1095
-
1096
- }
1097
- '''
1098
-
1099
- print(json_sort(json_raw))
1100
-
1101
- {
1102
- "editor.minimap.enabled": false,
1103
- "http.proxy": "http://127.0.0.1:1087",
1104
- "markdown.preview.fontSize": 14,
1105
- "workbench.iconTheme": "vscode-icons"
1106
- }
1107
- """
1120
+ # json_raw = '''
1121
+ # {
1122
+ # "markdown.preview.fontSize": 14,
1123
+ # "editor.minimap.enabled": false,
1124
+ # "workbench.iconTheme": "vscode-icons",
1125
+ # "http.proxy": "http://127.0.0.1:1087"
1126
+ # }
1127
+ # '''
1128
+ #
1129
+ # print(json_sort(json_raw))
1130
+ #
1131
+ # {
1132
+ # "editor.minimap.enabled": false,
1133
+ # "http.proxy": "http://127.0.0.1:1087",
1134
+ # "markdown.preview.fontSize": 14,
1135
+ # "workbench.iconTheme": "vscode-icons"
1136
+ # }
1108
1137
 
1109
1138
 
1110
1139
  def json_sort(
@@ -1112,10 +1141,12 @@ def json_sort(
1112
1141
  debug: bool = False,
1113
1142
  **kwargs
1114
1143
  ) -> dict | None:
1144
+ """JSON Sort"""
1115
1145
  try:
1116
1146
  return json.dumps(json.loads(string), indent=4, sort_keys=True, **kwargs) if v_true(string, str, debug=debug) else None
1117
1147
  except Exception as e:
1118
- logger.exception(e) if v_true(debug, bool) else next
1148
+ if v_true(debug, bool):
1149
+ logger.exception(e)
1119
1150
  return None
1120
1151
 
1121
1152
 
@@ -1132,31 +1163,33 @@ def delete_files(
1132
1163
  if v_true(files, str, debug=debug) and check_file_type(files, 'file', debug=debug):
1133
1164
 
1134
1165
  os.remove(files)
1135
- logger.success('deleted file: {}'.format(files)) if v_true(debug, bool) else next
1166
+ if v_true(debug, bool):
1167
+ logger.success(f'deleted file: {files}')
1136
1168
  return True
1137
1169
 
1138
- elif v_true(files, list, debug=debug):
1170
+ if v_true(files, list, debug=debug):
1139
1171
 
1140
1172
  for _file in files:
1141
1173
 
1142
1174
  if v_true(_file, str, debug=debug) and check_file_type(_file, 'file', debug=debug):
1143
1175
  try:
1144
1176
  os.remove(_file)
1145
- logger.success('deleted file: {}'.format(_file))
1177
+ logger.success(f'deleted file: {_file}')
1146
1178
  except Exception as e:
1147
- logger.error('error file: {} {}'.format(_file, e))
1179
+ logger.error(f'error file: {_file} {e}')
1148
1180
  else:
1149
- logger.error('error file: {}'.format(_file))
1181
+ logger.error(f'error file: {_file}')
1150
1182
 
1151
1183
  return True
1152
1184
 
1153
- else:
1185
+ if v_true(debug, bool):
1186
+ logger.error(f'error file: {files}')
1154
1187
 
1155
- logger.error('error file: {}'.format(files)) if v_true(debug, bool) else next
1156
- return False
1188
+ return False
1157
1189
 
1158
1190
  except Exception as e:
1159
- logger.exception(e) if v_true(debug, bool) else next
1191
+ if v_true(debug, bool):
1192
+ logger.exception(e)
1160
1193
  return False
1161
1194
 
1162
1195
 
@@ -1192,7 +1225,10 @@ def delete_directory(
1192
1225
  if v_true(directory, str, debug=debug) and check_file_type(directory, 'dir', debug=debug):
1193
1226
 
1194
1227
  rmtree(directory)
1195
- logger.success('deleted directory: {}'.format(directory)) if v_true(debug, bool) else next
1228
+
1229
+ if v_true(debug, bool):
1230
+ logger.success(f'deleted directory: {directory}')
1231
+
1196
1232
  return True
1197
1233
 
1198
1234
  elif v_true(directory, list, debug=debug):
@@ -1202,21 +1238,25 @@ def delete_directory(
1202
1238
  if v_true(_dir, str, debug=debug) and check_file_type(_dir, 'dir', debug=debug):
1203
1239
  try:
1204
1240
  rmtree(_dir)
1205
- logger.success('deleted directory: {}'.format(_dir)) if v_true(debug, bool) else next
1241
+ if v_true(debug, bool):
1242
+ logger.success(f'deleted directory: {_dir}')
1206
1243
  except Exception as e:
1207
- logger.error('error directory: {} {}'.format(_dir, e)) if v_true(debug, bool) else next
1244
+ if v_true(debug, bool):
1245
+ logger.error(f'error directory: {_dir} {e}')
1208
1246
  else:
1209
- logger.error('error directory: {}'.format(_dir)) if v_true(debug, bool) else next
1247
+ if v_true(debug, bool):
1248
+ logger.error(f'error directory: {_dir}')
1210
1249
 
1211
1250
  return True
1212
1251
 
1213
1252
  else:
1214
-
1215
- logger.error('error directory: {}'.format(directory)) if v_true(debug, bool) else next
1253
+ if v_true(debug, bool):
1254
+ logger.error(f'error directory: {directory}')
1216
1255
  return False
1217
1256
 
1218
1257
  except Exception as e:
1219
- logger.exception(e) if v_true(debug, bool) else next
1258
+ if v_true(debug, bool):
1259
+ logger.exception(e)
1220
1260
  return False
1221
1261
 
1222
1262
 
@@ -1234,37 +1274,41 @@ def process_pool(
1234
1274
  """
1235
1275
  多线程(MultiThread) | 多进程(MultiProcess)
1236
1276
  """
1237
- """
1238
- ThreadPool 线程池
1239
- ThreadPool 共享内存, Pool 不共享内存
1240
- ThreadPool 可以解决 Pool 在某些情况下产生的 Can't pickle local object 的错误
1241
- https://stackoverflow.com/a/58897266
1242
- """
1277
+ # ThreadPool 线程池
1278
+ # ThreadPool 共享内存, Pool 不共享内存
1279
+ # ThreadPool 可以解决 Pool 在某些情况下产生的 Can't pickle local object 的错误
1280
+ # https://stackoverflow.com/a/58897266
1243
1281
  try:
1244
1282
 
1245
1283
  # 处理数据
1246
- logger.info(f"data split ......") if v_true(debug, bool) else next
1284
+ if v_true(debug, bool):
1285
+ logger.info("data split ......")
1247
1286
  if len(process_data) <= process_num:
1248
1287
  process_num = len(process_data)
1249
1288
  _data = process_data
1250
1289
  else:
1251
1290
  _data = list_split(process_data, process_num, equally=True, debug=debug)
1252
- logger.info(f"data: {_data}") if v_true(debug, bool) else next
1291
+
1292
+ if v_true(debug, bool):
1293
+ logger.info(f"data: {_data}")
1253
1294
 
1254
1295
  # 执行函数
1255
1296
  if v_true(thread, bool):
1256
1297
  # 多线程
1257
- logger.info(f"execute multi thread ......") if v_true(debug, bool) else next
1298
+ if v_true(debug, bool):
1299
+ logger.info("execute multi thread ......")
1258
1300
  with ThreadPool(process_num, **kwargs) as p:
1259
1301
  return p.map(process_func, _data)
1260
1302
  else:
1261
1303
  # 多进程
1262
- logger.info(f"execute multi process ......") if v_true(debug, bool) else next
1304
+ if v_true(debug, bool):
1305
+ logger.info("execute multi process ......")
1263
1306
  with Pool(process_num, **kwargs) as p:
1264
1307
  return p.map(process_func, _data)
1265
1308
 
1266
1309
  except Exception as e:
1267
- logger.exception(e) if v_true(debug, bool) else next
1310
+ if v_true(debug, bool):
1311
+ logger.exception(e)
1268
1312
  return False
1269
1313
 
1270
1314
 
@@ -1276,6 +1320,7 @@ def new_process(
1276
1320
  debug: bool = False,
1277
1321
  **kwargs
1278
1322
  ) -> Thread | Process | bool:
1323
+ """New Process"""
1279
1324
  try:
1280
1325
  if v_true(thread, bool):
1281
1326
  process = Thread(target=process_func, args=process_data, **kwargs)
@@ -1285,7 +1330,8 @@ def new_process(
1285
1330
  process.start()
1286
1331
  return process
1287
1332
  except Exception as e:
1288
- logger.exception(e) if v_true(debug, bool) else next
1333
+ if v_true(debug, bool):
1334
+ logger.exception(e)
1289
1335
  return False
1290
1336
 
1291
1337
 
@@ -1296,20 +1342,25 @@ def create_empty_file(
1296
1342
  file: str | None = None,
1297
1343
  debug: bool = False
1298
1344
  ) -> str | None:
1345
+ """create empty file"""
1299
1346
  try:
1300
1347
  if file is None:
1301
1348
  # 当前时间戳(纳秒)
1302
1349
  timestamp = time.time_ns()
1303
- logger.info(f"timestamp: {timestamp}") if v_true(debug, bool) else next
1350
+ if v_true(debug, bool):
1351
+ logger.info(f"timestamp: {timestamp}")
1304
1352
  # 空文件路径
1305
1353
  file = f'/tmp/empty_file_{timestamp}.txt'
1306
1354
  # 创建一个空文件
1307
- logger.info(f"file: {file}") if v_true(debug, bool) else next
1355
+ if v_true(debug, bool):
1356
+ logger.info(f"file: {file}")
1357
+ # pylint: disable=R1732,disable=W1514
1308
1358
  open(file, 'w').close()
1309
1359
  # 返回文件路径
1310
1360
  return file
1311
1361
  except Exception as e:
1312
- logger.exception(e) if v_true(debug, bool) else next
1362
+ if v_true(debug, bool):
1363
+ logger.exception(e)
1313
1364
  return None
1314
1365
 
1315
1366
 
@@ -1317,6 +1368,7 @@ def create_empty_file(
1317
1368
 
1318
1369
 
1319
1370
  def uuid4_hex() -> str:
1371
+ """UUID"""
1320
1372
  return uuid4().hex
1321
1373
 
1322
1374
 
@@ -1330,7 +1382,8 @@ def increment_version(
1330
1382
  version_numbers[-1] = str(int(version_numbers[-1]) + 1)
1331
1383
  return '.'.join(version_numbers)
1332
1384
  except Exception as e:
1333
- logger.exception(e) if v_true(debug, bool) else next
1385
+ if v_true(debug, bool):
1386
+ logger.exception(e)
1334
1387
  return None
1335
1388
 
1336
1389
 
@@ -1346,7 +1399,8 @@ def make_directory(
1346
1399
  os.makedirs(directory)
1347
1400
  return True
1348
1401
  except Exception as e:
1349
- logger.exception(e) if v_true(debug, bool) else next
1402
+ if v_true(debug, bool):
1403
+ logger.exception(e)
1350
1404
  return False
1351
1405
 
1352
1406
  def change_directory(
@@ -1356,16 +1410,19 @@ def change_directory(
1356
1410
  """改变目录"""
1357
1411
  try:
1358
1412
  directory = str(directory) if v_true(directory, str, debug=debug) else next
1359
- logger.info(f"directory: {directory}") if v_true(debug, bool) else next
1413
+ if v_true(debug, bool):
1414
+ logger.info(f"directory: {directory}")
1360
1415
  if check_file_type(directory, 'dir', debug=debug):
1361
- logger.info(f"change directory to {directory}") if v_true(debug, bool) else next
1416
+ if v_true(debug, bool):
1417
+ logger.info(f"change directory to {directory}")
1362
1418
  os.chdir(directory)
1363
1419
  return True
1364
- else:
1365
- logger.error(f"no such directory: {directory}") if v_true(debug, bool) else next
1366
- return False
1420
+ if v_true(debug, bool):
1421
+ logger.error(f"no such directory: {directory}")
1422
+ return False
1367
1423
  except Exception as e:
1368
- logger.exception(e) if v_true(debug, bool) else next
1424
+ if v_true(debug, bool):
1425
+ logger.exception(e)
1369
1426
  return False
1370
1427
 
1371
1428
 
@@ -1376,16 +1433,20 @@ def load_toml_file(
1376
1433
  file: str = None,
1377
1434
  debug: bool = False
1378
1435
  ) -> dict | None:
1436
+ """Load TOML file"""
1379
1437
  try:
1380
1438
  info = '解析配置文件'
1381
- logger.info(f'{info}[执行]') if v_true(debug, bool) else next
1439
+ if v_true(debug, bool):
1440
+ logger.info(f'{info}[执行]')
1382
1441
  with open(file, "rb") as _file:
1383
1442
  config = toml_load(_file)
1384
- logger.success(f'{info}[成功]') if v_true(debug, bool) else next
1443
+ if v_true(debug, bool):
1444
+ logger.success(f'{info}[成功]')
1385
1445
  return config
1386
1446
  except Exception as e:
1387
- logger.error(f'{info}[失败]') if v_true(debug, bool) else next
1388
- logger.exception(e) if v_true(debug, bool) else next
1447
+ if v_true(debug, bool):
1448
+ logger.error(f'{info}[失败]')
1449
+ logger.exception(e)
1389
1450
  return None
1390
1451
 
1391
1452
 
@@ -1397,6 +1458,7 @@ def git_clone(
1397
1458
  log_prefix: str = '',
1398
1459
  debug: bool = False,
1399
1460
  ) -> bool:
1461
+ """GIT Clone"""
1400
1462
  try:
1401
1463
 
1402
1464
  # 日志前缀
@@ -1428,21 +1490,17 @@ def git_clone(
1428
1490
  )
1429
1491
  result_code = result.returncode
1430
1492
  result_info = result.stdout.splitlines()
1493
+ if v_true(debug, bool):
1494
+ logger.error(f'{log_prefix}unsuccessful')
1495
+ for i in result_info:
1496
+ logger.error(f'{log_prefix}{i}')
1431
1497
  if result_code == 0:
1432
- logger.success(f'{log_prefix}successful') if v_true(debug, bool) else next
1433
- if v_true(debug, bool):
1434
- for i in result_info:
1435
- logger.success(f'{log_prefix}{i}') if v_true(debug, bool) else next
1436
1498
  return True
1437
- else:
1438
- logger.error(f'{log_prefix}unsuccessful') if v_true(debug, bool) else next
1439
- if v_true(debug, bool):
1440
- for i in result_info:
1441
- logger.error(f'{log_prefix}{i}') if v_true(debug, bool) else next
1442
- return False
1499
+ return False
1443
1500
  except Exception as e:
1444
- logger.error(f'{log_prefix}unsuccessful') if v_true(debug, bool) else next
1445
- logger.exception(e) if v_true(debug, bool) else next
1501
+ if v_true(debug, bool):
1502
+ logger.error(f'{log_prefix}unsuccessful')
1503
+ logger.exception(e)
1446
1504
  return False
1447
1505
 
1448
1506
 
@@ -1451,18 +1509,20 @@ def url_parse(
1451
1509
  scheme: str = 'http',
1452
1510
  debug: bool = False
1453
1511
  ) -> ParseResult:
1512
+ """URL Parse"""
1454
1513
  none_result = ParseResult(scheme='', netloc='', path='', params='', query='', fragment='')
1455
1514
  try:
1456
- logger.info(f'url: {url}') if v_true(debug, bool) else next
1515
+ if v_true(debug, bool):
1516
+ logger.info(f'url: {url}')
1457
1517
  # 如果没有 scheme 的话, 字符串是不解析的. 所以, 如果没有 scheme, 就添加一个 scheme, 默认添加 http
1458
1518
  if v_true(url, str) and (url.find('://') == -1) and v_true(scheme, str):
1459
1519
  url = f'{scheme}://{url}'
1460
1520
  if v_true(url, str):
1461
1521
  return urlparse(url)
1462
- else:
1463
- return none_result
1522
+ return none_result
1464
1523
  except Exception as e:
1465
- logger.exception(e) if v_true(debug, bool) else next
1524
+ if v_true(debug, bool):
1525
+ logger.exception(e)
1466
1526
  return none_result
1467
1527
 
1468
1528
  # def debug_log(