oafuncs 0.0.98.3__py3-none-any.whl → 0.0.98.4__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.
@@ -1,151 +1,40 @@
1
- #!/usr/bin/env python
2
- # coding=utf-8
3
- """
4
- Author: Liu Kun && 16031215@qq.com
5
- Date: 2024-12-01 19:32:25
6
- LastEditors: Liu Kun && 16031215@qq.com
7
- LastEditTime: 2024-12-10 11:16:36
8
- FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_down\\test.py
9
- Description:
10
- EditPlatform: vscode
11
- ComputerInfo: XPS 15 9510
12
- SystemInfo: Windows 11
13
- Python Version: 3.12
14
- """
15
-
16
- import os
17
- import random
18
1
  import re
19
2
 
20
3
 
21
- def is_valid_user_agent(user_agent):
22
- # 简单的正则表达式来检查User Agent的格式
23
- # 这个正则表达式检查User Agent是否包含常见的浏览器信息格式
4
+ def is_valid_ua(ua):
5
+ # 更宽松的 UA 验证规则
24
6
  pattern = re.compile(
25
- r"^(?:(?:Mozilla|Opera|Chrome|Safari|Edg|OPR)/[\d.]+)"
26
- r"(?:\s(?:\(.*?\)))?"
27
- r"(?:\s(?:Gecko|AppleWebKit|KHTML, like Gecko|Version|Edge|OPR)/[\d.]+)?"
28
- r"(?:\s.*?(?:rv:|Version/|Ubuntu|Macintosh|Windows|X11|Linux|CrOS|FreeBSD|OpenBSD|NetBSD|iPhone|iPad|iPod|Android|BlackBerry|BB10|Mobile|Symbian|Windows Phone|IEMobile|Opera Mini|Opera Mobi|UCBrowser|MQQBrowser|baiduboxapp|baidubrowser|Safari|Firefox|MSIE|Trident|Edge|EdgA|Chrome|CriOS|Vivaldi|Sleipnir|Midori|ELinks|Lynx|w3m|Arora|Epiphany|Konqueror|Dillo|Netscape|SeaMonkey|K-Meleon|Camino|Iceape|Galeon|GranParadiso|Iceweasel|Firefox|Fennec|Conkeror|PaleMoon|Uzbl|QupZilla|Otter|Waterfox|Basilisk|Cyberfox|PaleMoon|GNU IceCat|GNU IceWeasel|IceCat|IceWeasel|Seamonkey|Iceape|Firefox|Epiphany|Web|Safari|Android|Mobile|BlackBerry|BB10|Tablet|Silk|Kindle|FxiOS|Focus|SamsungBrowser|browser|AppleWebKit|Puffin|DuckDuckGo|YaBrowser|Yandex|Amigo|NokiaBrowser|OviBrowser|OneBrowser|Chrome|Firefox|Safari|OPR|Coast|Mercury|Silk|Skyfire|IEMobile|Bolt|Jasmine|NativeHost|Crosswalk|TizenBrowser|SailfishBrowser|SamsungBrowser|Silk-Accelerated|UCBrowser|Quark|XiaoMi|OnePlus|Vivo|Oppo|Realme|Meizu|Lenovo|Huawei|ZTE|Alcatel|Sony|Nokia|LG|HTC|Asus|Acer|Motorola|Samsung)/[\d.]+)?$"
7
+ r"""
8
+ ^Mozilla/(4\.0|5\.0) # 必须以 Mozilla/4.0 或 5.0 开头
9
+ \s+ # 空格
10
+ \(.*?\) # 操作系统信息
11
+ \s+ # 空格
12
+ (AppleWebKit/|Gecko/|Trident/|Version/|Edge/)? # 浏览器引擎或版本标识(可选)
13
+ \d+(\.\d+)* # 至少一个版本号(小数部分可选)
14
+ .* # 允许后续扩展信息
15
+ $ # 行尾
16
+ """,
17
+ re.VERBOSE,
29
18
  )
19
+ return re.match(pattern, ua.strip()) is not None
30
20
 
31
- # 使用正则表达式匹配User Agent字符串
32
- if pattern.match(user_agent):
33
- return True
34
- else:
35
- return False
36
-
37
-
38
- def get_ua():
39
- current_dir = os.path.dirname(os.path.abspath(__file__))
40
- ua_file_txt = os.path.join(current_dir, "User_Agent-list.txt")
41
-
42
- with open(ua_file_txt, "r") as f:
43
- ua_list = f.readlines()
44
- # 去掉换行符和空行
45
- ua_list = [line.strip() for line in ua_list if line.strip()]
46
21
 
47
- return random.choice(ua_list)
22
+ def main():
23
+ input_file = r"E:\Code\Python\My_Funcs\OAFuncs\oafuncs\oa_down\User_Agent-list-old.txt"
24
+ output_file = r"E:\Code\Python\My_Funcs\OAFuncs\oafuncs\oa_down\User_Agent-list.txt"
48
25
 
26
+ valid_uas = []
27
+ with open(input_file, "r", encoding="utf-8") as f:
28
+ for line in f:
29
+ line = line.strip()
30
+ if line and is_valid_ua(line):
31
+ valid_uas.append(line)
49
32
 
50
- def get_ua_org():
51
- ua_list = [
52
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60",
53
- "Opera/8.0 (Windows NT 5.1; U; en)",
54
- "Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50",
55
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50",
56
- "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
57
- "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
58
- "Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/build-1107180945; U; en-GB) Presto/2.8.149 Version/11.10",
59
- "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0",
60
- "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10",
61
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv,2.0.1) Gecko/20100101 Firefox/4.0.1",
62
- "Mozilla/5.0 (Windows NT 6.1; rv,2.0.1) Gecko/20100101 Firefox/4.0.1",
63
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
64
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36",
65
- "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
66
- "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
67
- "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
68
- "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
69
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
70
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
71
- "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16",
72
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
73
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36",
74
- "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
75
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)",
76
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11",
77
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER",
78
- "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)",
79
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)",
80
- "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)",
81
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)",
82
- "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0",
83
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0)",
84
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)",
85
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.3.4000 Chrome/30.0.1599.101 Safari/537.36",
86
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
87
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36",
88
- "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4094.1 Safari/537.36",
89
- "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
90
- "Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
91
- "Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
92
- "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
93
- "Mozilla/5.0 (Linux; U; Android 2.2.1; zh-cn; HTC_Wildfire_A3333 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
94
- "Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
95
- "MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
96
- "Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/build-1107180945; U; en-GB) Presto/2.8.149 Version/11.10",
97
- "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13",
98
- "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.337 Mobile Safari/534.1+",
99
- "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 TouchPad/1.0",
100
- "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;",
101
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
102
- "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
103
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
104
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)",
105
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; The World)",
106
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)",
107
- "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser)",
108
- "Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
109
- "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124",
110
- "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; HTC; Titan)",
111
- "UCWEB7.0.2.37/28/999",
112
- "NOKIA5700/UCWEB7.0.2.37/28/999",
113
- "Openwave/UCWEB7.0.2.37/28/999",
114
- "Openwave/UCWEB7.0.2.37/28/999",
115
- ]
116
- with open(newtxtfile, "w") as f:
117
- for line in ua_list:
118
- f.write(line + "\n")
119
- # print(f'Using User-Agent: {ua}')
120
- ua = random.choice(ua_list)
121
- return ua
33
+ with open(output_file, "w", encoding="utf-8") as f:
34
+ f.write("\n".join(valid_uas))
122
35
 
36
+ print(f"[Linux 兼容模式] 有效UA已保存到 {output_file},共 {len(valid_uas)} 条")
123
37
 
124
- # get_ua_org()
125
38
 
126
39
  if __name__ == "__main__":
127
- txtfile = r"E:\Code\Python\My_Funcs\OAFuncs\oafuncs\oa_down\User_Agent-list.txt"
128
-
129
- with open(txtfile, "r") as f:
130
- lines = f.readlines()
131
- # 去掉换行符和空行
132
- lines = [line.strip() for line in lines if line.strip()]
133
- """ new_line = []
134
- for i in range(len(lines)):
135
- if '/' in lines[i]:
136
- new_line.append(lines[i])
137
- else:
138
- print(lines[i]) """
139
-
140
- new_line = []
141
- for line in lines:
142
- if is_valid_user_agent(line):
143
- # print(line)
144
- new_line.append(line)
145
- else:
146
- print(f"Invalid User-Agent: {line}")
147
-
148
- newtxtfile = r"E:\Code\Python\My_Funcs\OAFuncs\oafuncs\oa_down\ua_list_new.txt"
149
- with open(newtxtfile, "w") as f:
150
- for line in new_line:
151
- f.write(line + "\n")
40
+ main()
oafuncs/oa_tool.py CHANGED
@@ -1,50 +1,120 @@
1
- from typing import Any, Iterable, List, Optional, Union
1
+ import datetime
2
+ import logging
3
+ from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
2
4
 
3
5
  from rich import print
4
6
 
7
+ from ._script.parallel import ParallelExecutor
8
+
5
9
  __all__ = ["PEx", "email", "pbar"]
6
10
 
7
11
 
8
- class PEx:
12
+ class PEx(ParallelExecutor):
9
13
  """
10
- PEx wraps ParallelExecutor and delegates all its methods,
11
- allowing direct calls to PEx methods to achieve the same effect as ParallelExecutor.
14
+ 并行执行器扩展类 (ParallelExecutor Extend)
12
15
 
13
- Example:
14
- # Create a PEx instance
15
- executor = PEx(max_workers=4)
16
+ 继承自 ParallelExecutor,提供更简洁的接口和增强功能:
16
17
 
17
- # Use the run method to execute parallel tasks
18
- result = executor.run(lambda x: x * x, [(i,) for i in range(5)])
19
- print(result) # Output: [0, 1, 4, 9, 16]
20
- """
18
+ 特点:
19
+ - 自动时间统计 (开始/结束时间、总耗时)
20
+ - 增强的错误处理机制
21
+ - 友好的统计输出格式
22
+ - 支持进度回调函数
21
23
 
22
- try:
23
- from ._script.parallel import ParallelExecutor
24
- except ImportError:
25
- raise ImportError("[red]ParallelExecutor could not be imported. Ensure the module '_script.parallel' exists and is accessible.[/red]")
24
+ 示例:
25
+ >>> with PEx() as executor:
26
+ ... results = executor.run(lambda x: x*2, [(i,) for i in range(5)])
27
+ ... print(executor.format_stats())
28
+ [2024-06-08 15:30:00] 成功处理5个任务 (耗时0.5秒)
26
29
 
27
- def __init__(self, *args: Any, **kwargs: Any) -> None:
30
+ 参数调整建议:
31
+ - 内存密集型任务:增大 mem_per_process
32
+ - I/O密集型任务:使用 mode='thread'
33
+ """
34
+
35
+ def __init__(
36
+ self,
37
+ max_workers: Optional[int] = None,
38
+ chunk_size: Optional[int] = None,
39
+ mem_per_process: float = 1.5, # 调大默认内存限制
40
+ timeout_per_task: int = 7200, # 延长默认超时时间
41
+ max_retries: int = 5, # 增加默认重试次数
42
+ progress_callback: Optional[Callable[[int, int], None]] = None,
43
+ ):
44
+ """
45
+ 初始化并行执行器
46
+
47
+ :param max_workers: 最大工作进程/线程数 (默认自动计算)
48
+ :param chunk_size: 任务分块大小 (默认自动优化)
49
+ :param mem_per_process: 单进程内存预估(GB)
50
+ :param timeout_per_task: 单任务超时时间(秒)
51
+ :param max_retries: 最大重试次数
52
+ :param progress_callback: 进度回调函数 (当前完成数, 总数)
28
53
  """
29
- Initialize a PEx instance, internally creating a ParallelExecutor instance.
54
+ # 时间记录扩展
55
+ self.start_dt = datetime.datetime.now()
56
+ self.end_dt = None
57
+ self.progress_callback = progress_callback
58
+
59
+ super().__init__(max_workers=max_workers, chunk_size=chunk_size, mem_per_process=mem_per_process, timeout_per_task=timeout_per_task, max_retries=max_retries)
30
60
 
31
- Args:
32
- *args: Positional arguments passed to ParallelExecutor.
33
- **kwargs: Keyword arguments passed to ParallelExecutor.
61
+ logging.info(f"PEx initialized at {self.start_dt:%Y-%m-%d %H:%M:%S}")
62
+
63
+ def run(self, func: Callable, params: List[Tuple], chunk_size: Optional[int] = None) -> List[Any]:
34
64
  """
35
- self.executor = self.ParallelExecutor(*args, **kwargs)
65
+ 执行并行任务 (增强版)
36
66
 
37
- def __getattr__(self, attr: str) -> Any:
67
+ :param func: 目标函数,需能序列化(pickle)
68
+ :param params: 参数列表,每个元素为参数元组
69
+ :param chunk_size: 可选的分块大小
70
+ :return: 结果列表,与输入顺序一致
38
71
  """
39
- Delegate all undefined attribute access to the internal ParallelExecutor instance.
72
+ total_tasks = len(params)
73
+ if self.progress_callback:
74
+ self.progress_callback(0, total_tasks)
75
+
76
+ results = super().run(func, params, chunk_size)
77
+
78
+ if self.progress_callback:
79
+ self.progress_callback(total_tasks, total_tasks)
80
+
81
+ return results
82
+
83
+ def shutdown(self):
84
+ """增强关闭方法,记录结束时间"""
85
+ self.end_dt = datetime.datetime.now()
86
+ super().shutdown()
87
+ logging.info(f"PEx shutdown at {self.end_dt:%Y-%m-%d %H:%M:%S}")
88
+
89
+ def get_stats(self) -> Dict[str, Any]:
90
+ """获取统计信息 (扩展时间数据)"""
91
+ stats = super().get_stats()
92
+ stats.update({"start_time": self.start_dt.strftime("%Y-%m-%d %H:%M:%S"), "end_time": self.end_dt.strftime("%Y-%m-%d %H:%M:%S") if self.end_dt else "运行中", "total_seconds": round((self.end_dt - self.start_dt).total_seconds(), 3) if self.end_dt else None})
93
+ return stats
94
+
95
+ def format_stats(self) -> str:
96
+ """生成友好统计报告"""
97
+ stats = self.get_stats()
98
+ report = [
99
+ f"[{stats['start_time']}] 并行任务统计报告",
100
+ f"▪ 平台环境:{stats['platform'].upper()} ({stats['mode']}模式)",
101
+ f"▪ 资源使用:{stats['workers']}个工作进程 | 分块大小{stats['chunk_size']}",
102
+ f"▪ 任务统计:成功处理{stats['total_tasks']}个任务 (失败{stats['total_tasks'] - sum(1 for r in self.results if r is not None)})",
103
+ f"▪ 时间统计:总耗时{stats['total_seconds']}秒",
104
+ ]
105
+ if "avg_task_throughput" in stats:
106
+ report.append(f"▪ 吞吐性能:{stats['avg_task_throughput']:.1f} 任务/秒")
107
+ return "\n".join(report)
108
+
109
+ def __enter__(self):
110
+ """支持上下文管理器"""
111
+ return self
112
+
113
+ def __exit__(self, exc_type, exc_val, exc_tb):
114
+ """退出时自动关闭"""
115
+ self.shutdown()
40
116
 
41
- Args:
42
- attr (str): The name of the attribute to access.
43
117
 
44
- Returns:
45
- Any: The value of the corresponding attribute.
46
- """
47
- return getattr(self.executor, attr)
48
118
 
49
119
 
50
120
  def email(title: str = "Title", content: Optional[str] = None, send_to: str = "10001@qq.com") -> None:
@@ -91,7 +161,7 @@ def pbar(
91
161
 
92
162
  Returns:
93
163
  Any: An instance of ColorProgressBar.
94
-
164
+
95
165
  Example:
96
166
  >>> for i in pbar(range(10), description="Processing"):
97
167
  ... time.sleep(0.1)
@@ -117,3 +187,21 @@ def pbar(
117
187
  speed_estimate_period=speed_estimate_period,
118
188
  next_line=next_line,
119
189
  )
190
+
191
+
192
+ # 使用示例
193
+ if __name__ == "__main__":
194
+
195
+ def sample_task(x):
196
+ import time
197
+
198
+ time.sleep(0.1)
199
+ return x * 2
200
+
201
+ def progress_handler(current, total):
202
+ print(f"\r进度: {current}/{total} ({current / total:.1%})", end="")
203
+
204
+ with PEx(max_workers=4, progress_callback=progress_handler) as executor:
205
+ results = executor.run(sample_task, [(i,) for i in range(10)])
206
+
207
+ print("\n" + executor.format_stats())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oafuncs
3
- Version: 0.0.98.3
3
+ Version: 0.0.98.4
4
4
  Summary: Oceanic and Atmospheric Functions
5
5
  Home-page: https://github.com/Industry-Pays/OAFuncs
6
6
  Author: Kun Liu
@@ -25,6 +25,7 @@ Requires-Dist: rich
25
25
  Requires-Dist: pathlib
26
26
  Requires-Dist: requests
27
27
  Requires-Dist: bs4
28
+ Requires-Dist: httpx
28
29
  Requires-Dist: matplotlib
29
30
  Requires-Dist: netCDF4
30
31
  Requires-Dist: xlrd
@@ -7,7 +7,7 @@ oafuncs/oa_file.py,sha256=goF5iRXJFFCIKhIjlkCnYYt0EYlJb_4r8AeYNZ0-SOk,16209
7
7
  oafuncs/oa_help.py,sha256=_4AZgRDq5Or0vauNvq5IDDHIBoBfdOQtzak-mG1wwAw,4537
8
8
  oafuncs/oa_nc.py,sha256=L1gqXxg93kIDsMOa87M0o-53KVmdqCipnXeF9XfzfY8,10513
9
9
  oafuncs/oa_python.py,sha256=NkopwkYFGSEuVljnTBvXCl6o2CeyRNBqRXSsUl3euEE,5192
10
- oafuncs/oa_tool.py,sha256=8y0X3KXNLbYchr5hBHCwhdsA_1VDEnzsZVqcM5sNeog,4484
10
+ oafuncs/oa_tool.py,sha256=UNdiXKWfk860eb01vSGH8XN_Bd3CP7ihaspRrudday0,7983
11
11
  oafuncs/_data/hycom.png,sha256=MadKs6Gyj5n9-TOu7L4atQfTXtF9dvN9w-tdU9IfygI,10945710
12
12
  oafuncs/_data/oafuncs.png,sha256=o3VD7wm-kwDea5E98JqxXl04_78cBX7VcdUt7uQXGiU,3679898
13
13
  oafuncs/_script/cprogressbar.py,sha256=wRU3SFPFtMI7ER26tTzg223kVKNo5RDWE9CzdIgUsuE,15771
@@ -15,17 +15,18 @@ oafuncs/_script/email.py,sha256=lL4HGKrr524-g0xLlgs-4u7x4-u7DtgNoD9AL8XJKj4,3058
15
15
  oafuncs/_script/netcdf_merge.py,sha256=_EPF9Xj4HOVC9sZpi1lt62-Aq6pMlgsgwaajEBLhW6g,5092
16
16
  oafuncs/_script/netcdf_modify.py,sha256=sGRUYNhfGgf9JV70rnBzw3bzuTRSXzBTL_RMDnDPeLQ,4552
17
17
  oafuncs/_script/netcdf_write.py,sha256=iO1Qv9bp6RLiw1D8Nrv7tX_8X-diUZaX3Nxhk6pJ5Nw,8556
18
- oafuncs/_script/parallel.py,sha256=FS9FgaByq2yb9j6nL-Y0xP1VLvp4USMLBFMRsJDoqeQ,21848
19
- oafuncs/_script/parallel_example_usage.py,sha256=uLvE7iwkMn9Cyq6-wk5_RpbQk7PXM9d16-26lTknW9s,2646
18
+ oafuncs/_script/parallel.py,sha256=dRT7w_rBnR3mZkUlO6v6j05SwBTQpTccOna5CXI5Msg,8196
19
+ oafuncs/_script/parallel_test.py,sha256=0GBqZOX7IaCOKF2t1y8N8YYu53GJ33OkfsWgpvZNqM4,372
20
20
  oafuncs/_script/plot_dataset.py,sha256=zkSEnO_-biyagorwWXPoihts_cwuvripzEt-l9bHJ2E,13989
21
21
  oafuncs/_script/replace_file_content.py,sha256=eCFZjnZcwyRvy6b4mmIfBna-kylSZTyJRfgXd6DdCjk,5982
22
- oafuncs/oa_down/User_Agent-list.txt,sha256=pazxSip8_lphEBOPHG902zmIBUg8sBKXgmqp_g6j_E4,661062
22
+ oafuncs/oa_down/User_Agent-list.txt,sha256=pHaMlElMvZ8TG4vf4BqkZYKqe0JIGkr4kCN0lM1Y9FQ,514295
23
23
  oafuncs/oa_down/__init__.py,sha256=kRX5eTUCbAiz3zTaQM1501paOYS_3fizDN4Pa0mtNUA,585
24
- oafuncs/oa_down/hycom_3hourly.py,sha256=Xi6LuD3DIiYq2gYYBVxY3OpVvfy3RkSMzNkOX2isSK8,52915
24
+ oafuncs/oa_down/hycom_3hourly.py,sha256=heG4L_eyPsc8pgUASCXYYJEdPGAY7rtRWQsiy-qrSxE,54202
25
25
  oafuncs/oa_down/hycom_3hourly_20250407.py,sha256=DQd_NmQgmSqu7jsrfpDB7k23mkUEy9kyWs-dLUg7GDw,64472
26
+ oafuncs/oa_down/hycom_3hourly_20250416.py,sha256=X_fcV_xeJtYD-PB3GRdFWNHMPOVUYgh17MgWOtrdIbc,53493
26
27
  oafuncs/oa_down/idm.py,sha256=4z5IvgfTyIKEI1kOtqXZwN7Jnfjwp6qDBOIoVyOLp0I,1823
27
28
  oafuncs/oa_down/literature.py,sha256=2bF9gSKQbzcci9LcKE81j8JEjIJwON7jbwQB3gDDA3E,11331
28
- oafuncs/oa_down/test_ua.py,sha256=0IQq3NjqfNr7KkyjS_U-a4mYu-r-E7gzawwo4IfEa6Y,10851
29
+ oafuncs/oa_down/test_ua.py,sha256=l8MCD6yU2W75zRPTDKUZTJhCWNF9lfk-MiSFqAqKH1M,1398
29
30
  oafuncs/oa_down/user_agent.py,sha256=TsPcAxFmMTYAEHRFjurI1bQBJfDhcA70MdHoUPwQmks,785
30
31
  oafuncs/oa_model/__init__.py,sha256=__ImltHkP1bSsIpsmKpDE8QwwA-2Z8K7mZUHGGcRdro,484
31
32
  oafuncs/oa_model/roms/__init__.py,sha256=g-_iv2vUFUnSsKWc7pzGRfkNUvhxfG-Bn4deqfGwxyo,474
@@ -36,8 +37,8 @@ oafuncs/oa_sign/__init__.py,sha256=QKqTFrJDFK40C5uvk48GlRRbGFzO40rgkYwu6dYxatM,5
36
37
  oafuncs/oa_sign/meteorological.py,sha256=8091SHo2L8kl4dCFmmSH5NGVHDku5i5lSiLEG5DLnOQ,6489
37
38
  oafuncs/oa_sign/ocean.py,sha256=xrW-rWD7xBWsB5PuCyEwQ1Q_RDKq2KCLz-LOONHgldU,5932
38
39
  oafuncs/oa_sign/scientific.py,sha256=a4JxOBgm9vzNZKpJ_GQIQf7cokkraV5nh23HGbmTYKw,5064
39
- oafuncs-0.0.98.3.dist-info/licenses/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
40
- oafuncs-0.0.98.3.dist-info/METADATA,sha256=1-5l6aAaOFaZ9U0pSE6f1944hrE01bLGCBLPonbEXeU,4220
41
- oafuncs-0.0.98.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
42
- oafuncs-0.0.98.3.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
43
- oafuncs-0.0.98.3.dist-info/RECORD,,
40
+ oafuncs-0.0.98.4.dist-info/licenses/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
41
+ oafuncs-0.0.98.4.dist-info/METADATA,sha256=VWSW69LEhmMu9FHH_e0WcNT-YXme3mdxlNvMedU48tY,4242
42
+ oafuncs-0.0.98.4.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
43
+ oafuncs-0.0.98.4.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
44
+ oafuncs-0.0.98.4.dist-info/RECORD,,
@@ -1,83 +0,0 @@
1
- #!/usr/bin/env python
2
- # coding=utf-8
3
- """
4
- Author: Liu Kun && 16031215@qq.com
5
- Date: 2025-03-18 19:14:19
6
- LastEditors: Liu Kun && 16031215@qq.com
7
- LastEditTime: 2025-03-18 19:18:38
8
- FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\_script\\parallel_example_usage.py
9
- Description:
10
- EditPlatform: vscode
11
- ComputerInfo: XPS 15 9510
12
- SystemInfo: Windows 11
13
- Python Version: 3.12
14
- """
15
-
16
- import logging
17
- import time
18
- from auto_optimized_parallel_executor import ParallelExecutor
19
-
20
- # 设置日志
21
- logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
22
-
23
-
24
- # 示例函数
25
- def compute_intensive_task(n):
26
- """计算密集型任务示例"""
27
- result = 0
28
- for i in range(n):
29
- result += i**0.5
30
- return result
31
-
32
-
33
- def io_intensive_task(seconds, value):
34
- """IO密集型任务示例"""
35
- time.sleep(seconds) # 模拟IO操作
36
- return f"Processed {value}"
37
-
38
-
39
- def main():
40
- # 创建自动优化的执行器
41
- executor = ParallelExecutor()
42
-
43
- # 打印选择的模式和工作线程/进程数量
44
- print(f"自动选择的执行模式: {executor.mode}")
45
- print(f"自动选择的工作线程/进程数: {executor.max_workers}")
46
- print(f"运行平台: {executor.platform}")
47
-
48
- # 示例1: 计算密集型任务
49
- print("\n运行计算密集型任务...")
50
- params = [(1000000,) for _ in range(20)]
51
- results = executor.run(compute_intensive_task, params)
52
- print(f"完成计算密集型任务,结果数量: {len(results)}")
53
-
54
- # 示例2: IO密集型任务
55
- print("\n运行IO密集型任务...")
56
- io_params = [(0.1, f"item-{i}") for i in range(30)]
57
- io_results = executor.run(io_intensive_task, io_params)
58
- print(f"完成IO密集型任务,结果示例: {io_results[:3]}")
59
-
60
- # 示例3: 使用map接口
61
- print("\n使用map接口...")
62
- numbers = list(range(1, 11))
63
- squared = list(executor.map(lambda x: x * x, numbers))
64
- print(f"Map结果: {squared}")
65
-
66
- # 示例4: 使用imap_unordered接口(乱序返回结果)
67
- print("\n使用imap_unordered接口...")
68
- for i, result in enumerate(executor.imap_unordered(lambda x: x * x * x, range(1, 11))):
69
- print(f"收到结果 #{i}: {result}")
70
-
71
- # 示例5: 使用gather执行不同函数
72
- print("\n使用gather接口执行不同函数...")
73
- tasks = [(compute_intensive_task, (500000,)), (io_intensive_task, (0.2, "task1")), (io_intensive_task, (0.1, "task2")), (compute_intensive_task, (300000,))]
74
- gather_results = executor.gather(tasks)
75
- print(f"Gather结果: {gather_results}")
76
-
77
- # 关闭执行器
78
- executor.shutdown()
79
- print("\n执行器已关闭")
80
-
81
-
82
- if __name__ == "__main__":
83
- main()