-
大家好,转眼间就过去半年了,这次带来上半年最后一次干货合集,希望可以帮助到大家。1.Python中自动化运维应用详细指南 【转载】https://bbs.huaweicloud.com/forum/thread-02112186033372780040-1-1.html2.Python中多进程调试技巧指南【转载】https://bbs.huaweicloud.com/forum/thread-0254186033461767036-1-1.html3.Python中分布式框架Ray扩展的详细指南【转载】https://bbs.huaweicloud.com/forum/thread-0254186033514531037-1-1.html4.Go语言代码格式化的技巧分享【转载】https://bbs.huaweicloud.com/forum/thread-0291186033591572046-1-1.html5.利用Python脚本实现批量将图片转换为WebP格式【转载】https://bbs.huaweicloud.com/forum/thread-02127186033644703043-1-1.html6.python如何调用java的jar包【转载】https://bbs.huaweicloud.com/forum/thread-0254186033702816038-1-1.html7.Python多进程开发之如何轻松突破GIL瓶颈【转载】https://bbs.huaweicloud.com/forum/thread-02112186033758338041-1-1.html8.Python嵌套循环的实现示例【转载】https://bbs.huaweicloud.com/forum/thread-0234186033811542039-1-1.html9.使用Python绘制动态方块热力图【转载】https://bbs.huaweicloud.com/forum/thread-02112186033897928042-1-1.html10.Python实现安全密码生成器的示例代码【转载】https://bbs.huaweicloud.com/forum/thread-02112186033937396043-1-1.html11.GitLab文件的上传与下载方式【转载】https://bbs.huaweicloud.com/forum/thread-02101186034000720043-1-1.html12.git stash命令基本用法详解【转载】https://bbs.huaweicloud.com/forum/thread-0206186034045364030-1-1.html13.通过git命令查看项目连接的仓库地址的几种方法【转载】https://bbs.huaweicloud.com/forum/thread-02127186034104222044-1-1.html14.S3 标签字符清洗的正则表达式实践记录【转载】https://bbs.huaweicloud.com/forum/thread-0255186034229565036-1-1.html15.Git配置SSH密钥与私钥的教程(跨平台完整指南)【转载】https://bbs.huaweicloud.com/forum/thread-0206186034272730031-1-1.html
-
请问大家,如何解决在RDP远程连接断开后,flexus自动锁屏的问题,挂在后台的代码无法正常运行
-
深入理解 S3 标签字符清洗的正则表达式实践在构建与 AWS S3 相关的服务时,尤其是使用 S3 标签(Tag)作为资源标识或元数据时,确保标签值符合 AWS 的字符规范是非常重要的。否则,你可能会在上传对象、设置标签或调用 SDK 时遇到 InvalidTag 或 ValidationError 等问题。本文将结合一个具体的 Python 方法,剖析如何使用正则表达式 [^a-zA-Z0-9 äöüÄÖÜß\+\-=\._:/@] 对标签值进行有效的字符清洗。一、背景:S3 标签字符限制S3 标签值必须仅包含:大小写英文字母(a-zA-Z)数字(0-9)特定的特殊字符:空格( )、加号(+)、减号(-)、等号(=)、点号(.)、冒号(:)、斜杠(/)、at符号(@)UTF-8 字符集中某些额外字符,如德语中的 äöüÄÖÜß二、Python 示例代码123456import reclass S3Utils: @staticmethod def sanitize_tag_value(s: str) -> str: """只保留 S3 允许的字符,移除非法字符。""" return re.sub(r"[^a-zA-Z0-9 äöüÄÖÜß\+\-=\._:/@]", "", s)这段代码的核心在于 re.sub 函数,它通过正则表达式替换掉字符串中所有非法字符,只保留符合 S3 要求的字符。三、正则表达式解析让我们逐段分析这个正则表达式:[^...]:否定字符集合表示匹配所有不属于该集合的字符,是我们用来“过滤”的核心机制。[a-zA-Z0-9 ]:基本字母与数字允许所有的英文大小写字母和数字,以及空格。äöüÄÖÜß:德语扩展字符AWS 的字符集对于欧洲语种的支持,允许常见的德语变音字符和 ß。特殊符号部分:符号含义是否转义+加号是:\+-减号是:\-(放在开头或结尾避免歧义)=等号否.点号是:\.:冒号否/斜杠否@at符号否这些符号是 AWS 允许在标签中出现的元字符,用于分隔或传递业务信息。四、使用示例123test_str = "产品编号:ABC-123@测试#非法字符!"cleaned = S3Utils.sanitize_tag_value(test_str)print(cleaned) # 输出:产品编号ABC-123@测试非法字符可以看到:合法字符如 ABC-123@测试 被保留;非法字符如 # 和 ! 被移除。五、应用场景建议S3 标签预处理(推荐:上传标签前统一调用该函数)日志标记、对象分类(特别适合多语言内容)数据库入库前的字段清洗(可复用该正则)
-
安全密码的特点一个安全的密码通常具备以下特点:足够长度(至少12位以上)包含大小写字母包含数字包含特殊符号随机性高,不包含可预测的模式代码实现1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253import secretsimport string def generate_secure_password(length=12): """生成包含大小写字母、数字和特殊符号的强密码""" # 定义字符集 uppercase = string.ascii_uppercase lowercase = string.ascii_lowercase digits = string.digits symbols = '@#+*' # 组合所有字符类型 all_chars = uppercase + lowercase + digits + symbols # 确保密码包含至少一个每种字符类型 password = [ secrets.choice(uppercase), secrets.choice(lowercase), secrets.choice(digits), secrets.choice(symbols) ] # 填充剩余长度 remaining_length = length - 4 for _ in range(remaining_length): password.append(secrets.choice(all_chars)) # 打乱字符顺序增强随机性 secrets.SystemRandom().shuffle(password) return ''.join(password) def main(): print("=== 安全密码生成器 ===") while True: try: length = int(input("请输入密码长度(至少4位):")) if length < 4: print("错误:密码长度不能少于4位!") continue break except ValueError: print("错误:请输入有效数字!") password = generate_secure_password(length) print("\n生成的强密码:", password) print("密码强度:", "★" * length) if __name__ == "__main__": main()代码解析1.安全库的选择:本程序使用secrets模块而非传统的random模块。secrets专为安全敏感操作设计,提供真正的加密安全随机数。2.字符集设计:包含所有大小写字母、数字及常用特殊字符可以根据需要扩展特殊字符集3.确保密码复杂性:强制包含各类字符,确保至少有一个大写字母、一个小写字母、一个数字和一个特殊符号使用SystemRandom().shuffle()提供加密级别的随机洗牌,防止密码生成有规律4.用户友好设计:密码长度可自定义,但设置最小安全限制提供错误处理,防止用户输入无效数据实际应用场景创建新账户时生成强密码定期更换密码时使用为不同网站生成不同的安全密码作为密码管理器的一部分,自动生成并存储密码使用建议尽管本工具可以生成高强度密码,但仍建议:使用密码管理器安全存储生成的密码对重要账户启用双因素认证(2FA)不同网站使用不同密码定期更换密码进阶改进方向添加图形用户界面(GUI)实现密码强度评估功能增加可配置的密码规则(如排除易混淆字符)添加生成记忆性强但安全的密码短语功能集成到密码管理系统
-
为什么选择这种热力图?传统热力图通常只通过颜色深浅来表达数值大小,而我们今天要实现的版本增加了一个维度 ——方块面积。这种双变量可视化的优势在于:颜色感知更直观:人类视觉对颜色的敏感度极高,不同色调能快速传递数值层级面积大小强化差异:当数值差异较大时,面积变化比颜色变化更具冲击力信息密度更高:在有限空间内展示更多维度的数据特征这种可视化方式特别适合:特征重要性分析(如机器学习模型的特征权重)二维数据分布展示(如用户行为矩阵、市场份额分析)数据对比场景(如不同条件下的指标对比)代码实现:从 0 到 1 的可视化之旅先来看完整代码,我们将逐步拆解每一个神奇的步骤:1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950import numpy as npimport matplotlib.pyplot as plt # 随机生成一个 10x10 的矩阵,值域在 0 到 1 之间np.random.seed(0)data = np.random.rand(10, 10) fig, ax = plt.subplots(figsize=(8, 6)) # 创建颜色映射(使用 colormap)cmap = plt.cm.RdYlGnnorm = plt.Normalize(vmin=0, vmax=1) # 绘制方块for i in range(data.shape[0]): for j in range(data.shape[1]): value = data[i, j] color = cmap(norm(value)) size = value * 900 # 控制面积大小(最大 900) # 使用 scatter 绘制方块 ax.scatter(j + 1, 10 - i, s=size, c=[color], marker='s', edgecolor='black') # 设置坐标轴ax.set_xticks(np.arange(1, 11))ax.set_yticks(np.arange(1, 11))ax.set_xticklabels(np.arange(1, 11))ax.set_yticklabels(np.arange(1, 11))ax.set_xlabel("K (w)", fontsize=12)ax.set_ylabel("Samples", fontsize=12) # 添加标题ax.set_title("Square Heatmap Plot", fontsize=14, fontweight='bold') # 添加颜色条sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)sm.set_array([])cbar = plt.colorbar(sm, ax=ax)cbar.set_label("") # 添加网格线模拟边框ax.set_xlim(0.5, 10.5)ax.set_ylim(0.5, 10.5)ax.set_xticks(np.arange(0.5, 11.5, 1), minor=True)ax.set_yticks(np.arange(0.5, 11.5, 1), minor=True)ax.grid(which='minor', color='black', linewidth=1)ax.tick_params(which='minor', length=0) plt.tight_layout()plt.show()核心组件拆解:每一行代码都在做什么?1. 数据准备:打造可视化的基石12np.random.seed(0)data = np.random.rand(10, 10)np.random.seed(0) 是为了保证结果可复现,就像给随机数生成器设定一个 “起点”,这样别人运行代码时能得到和你一样的数据~np.random.rand(10, 10) 生成一个 10x10 的随机矩阵,数值范围在 0 到 1 之间。这里就是替换自己数据的关键位置!你可以:从文件读取数据:data = np.loadtxt('your_data.csv', delimiter=',')加载已有的 numpy 数组:data = np.array(your_custom_data)甚至手动定义矩阵:data = np.array([[0.1, 0.5], [0.8, 0.3]])提示: 如果你的数据值域不在 0-1 之间,后续的颜色映射和大小计算需要相应调整哦~2. 画布搭建:准备好展示数据的舞台1fig, ax = plt.subplots(figsize=(8, 6))plt.subplots() 创建一个 Figure 对象和一个 Axes 对象,这是 Matplotlib 绘图的标准流程~figsize=(8, 6) 设置画布大小为 8 英寸宽、6 英寸高,你可以根据数据量调整这个参数,比如数据是 20x20 的,可以设为 (10,10) 让每个方块更清晰。3. 颜色系统:让数据穿上绚丽的外衣12cmap = plt.cm.RdYlGnnorm = plt.Normalize(vmin=0, vmax=1)cmap = plt.cm.RdYlGn 选择了一个从红色到黄色再到绿色的颜色映射,数值小的地方显示红色,数值大的地方显示绿色,中间过渡自然~你可以换成其他颜色映射:plt.cm.viridis(蓝绿黄渐变,适合连续数据)plt.cm.coolwarm(蓝红渐变,适合正负值对比)plt.cm.Blues(单色系蓝色,适合单一趋势数据)norm = plt.Normalize(vmin=0, vmax=1) 定义了数值到颜色的映射规则,将数据范围归一化到 0-1,这样颜色变化能准确反映数值差异。如果你的数据值域是 5-100,这里要改成vmin=5, vmax=100哦!4. 方块绘制:数据可视化的核心逻辑1234567for i in range(data.shape[0]): for j in range(data.shape[1]): value = data[i, j] color = cmap(norm(value)) size = value * 900 # 控制面积大小(最大 900) ax.scatter(j + 1, 10 - i, s=size, c=[color], marker='s', edgecolor='black')这部分是代码的灵魂!我们通过双重循环遍历矩阵的每个元素:value = data[i, j] 取出当前位置的数值color = cmap(norm(value)) 将数值转换为对应的颜色,这里用到了前面定义的颜色映射和归一化规则size = value * 900 计算方块面积,数值越大方块越大。这里的 900 是一个缩放因子,你可以调整它来控制方块的大小范围,比如改成 500 让方块更小,或者 1500 让差异更明显~ax.scatter(...) 是绘制方块的关键函数:j + 1, 10 - i 是方块的坐标,注意这里10 - i是为了让 y 轴从上到下递增,符合矩阵的行列索引习惯s=size 控制面积大小c=[color] 设置颜色,注意用列表包裹颜色值marker='s' 将散点形状设为正方形(square),也可以换成'o'圆形、'^'三角形等edgecolor='black' 添加黑色边框,让每个方块更清晰可辨5. 细节优化:让图表更专业美观123456789101112131415161718192021222324# 设置坐标轴ax.set_xticks(np.arange(1, 11))ax.set_yticks(np.arange(1, 11))ax.set_xticklabels(np.arange(1, 11))ax.set_yticklabels(np.arange(1, 11))ax.set_xlabel("K (w)", fontsize=12)ax.set_ylabel("Samples", fontsize=12) # 添加标题ax.set_title("Square Heatmap Plot", fontsize=14, fontweight='bold') # 添加颜色条sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)sm.set_array([])cbar = plt.colorbar(sm, ax=ax)cbar.set_label("") # 添加网格线模拟边框ax.set_xlim(0.5, 10.5)ax.set_ylim(0.5, 10.5)ax.set_xticks(np.arange(0.5, 11.5, 1), minor=True)ax.set_yticks(np.arange(0.5, 11.5, 1), minor=True)ax.grid(which='minor', color='black', linewidth=1)ax.tick_params(which='minor', length=0)这部分是让图表从 “能用” 到 “精美” 的关键:坐标轴设置:明确 x 轴和 y 轴的刻度位置和标签,ax.set_xlabel和ax.set_ylabel可以换成你自己的变量名称,比如 “时间(小时)”“用户活跃度” 等。标题添加:ax.set_title让图表有一个清晰的主题,fontweight='bold'让标题更醒目。颜色条:这是热力图的 “翻译器”,告诉读者颜色对应的数值范围。sm.set_array([])是一个小技巧,用于初始化颜色映射对象。网格线与边框:这里用了一个巧妙的方法 —— 通过设置次要刻度(minor ticks)并绘制网格线,模拟出每个方块的边框。ax.set_xlim(0.5, 10.5)将坐标轴范围扩展到 0.5-10.5,这样 10x10 的矩阵刚好占据整个区域,网格线就像一个个小格子~自定义你的可视化:从模仿到创新1. 替换成你自己的数据正如前面提到的,数据生成部分是最容易替换的地方。假设你有一个从 Excel 中导出的 15x15 的用户行为数据矩阵,路径为user_behavior.csv,你可以这样做:123456# 从CSV文件读取数据data = np.loadtxt('user_behavior.csv', delimiter=',') # 或者使用pandas读取(更灵活)import pandas as pddata = pd.read_csv('user_behavior.csv').values如果你的数据值域不是 0-1,比如是 10-100,需要调整颜色映射和大小计算: 1234# 假设数据值域是10-100vmin, vmax = 10, 100norm = plt.Normalize(vmin=vmin, vmax=vmax)size = (value - vmin) / (vmax - vmin) * 900 # 归一化后计算大小2. 调整颜色映射和视觉效果如果你不喜欢 RdYlGn 颜色映射,可以尝试其他方案:123456# 冷色调到暖色调(适合显示数值递增趋势)cmap = plt.cm.Blues# 红黄色调(适合突出高数值区域)cmap = plt.cm.OrRd# 彩虹色调(适合展示复杂模式)cmap = plt.cm.rainbow3. 优化大数据量场景如果你的数据是 100x100 的大矩阵,直接绘制可能会显得拥挤,这时可以:调整画布大小:fig, ax = plt.subplots(figsize=(12, 12))减小边框和网格线宽度:ax.grid(which='minor', color='black', linewidth=0.5)取消边框:ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['left'].set_visible(False)4. 添加交互功能(进阶)如果想让图表更动态,可以使用matplotlib的交互功能或结合ipywidgets:1234567891011121314151617from matplotlib.widgets import Slider # 创建滑块来调整大小缩放因子ax_slider = plt.axes([0.25, 0.02, 0.65, 0.03])slider = Slider(ax_slider, 'Size Scale', 100, 2000, valinit=900) def update(val): scale = slider.val for i in range(data.shape[0]): for j in range(data.shape[1]): value = data[i, j] size = value * scale # 这里需要先清除之前的散点,再重新绘制 # 由于scatter返回的是PathCollection对象,可以保存后更新 fig.canvas.draw_idle() slider.on_changed(update)应用场景:让可视化解决实际问题这种双变量热力图在实际场景中能做什么?举几个栗子:1. 机器学习特征重要性可视化假设你训练了一个随机森林模型,想展示各特征的重要性:12# 假设feature_importances是形状为(20,)的数组data = feature_importances.reshape(4, 5) # 调整为4x5的矩阵便于可视化2. 市场份额分析展示不同地区、不同产品的市场占有率:123456789# 行:地区(华北、华东、华南、西北、西南)# 列:产品(A、B、C、D)data = np.array([ [0.35, 0.25, 0.15, 0.25], [0.28, 0.32, 0.18, 0.22], [0.40, 0.20, 0.15, 0.25], [0.22, 0.30, 0.25, 0.23], [0.25, 0.25, 0.30, 0.20]])3. 图像像素强度可视化将灰度图像转换为热力图展示:1234567from skimage import dataimport matplotlib.pyplot as plt # 加载示例图像image = data.camera()# 归一化到0-1data = image / 255.0注意事项:避坑指南方块重叠问题:当数值差异很大时,大的方块可能会覆盖小的方块。可以通过调整size的缩放因子或添加透明度来解决:1ax.scatter(..., alpha=0.8) # 添加透明度坐标轴标签旋转:当 x 轴标签较多时,可能会重叠,可以旋转标签: 1ax.set_xticklabels(np.arange(1, 11), rotation=45, ha='right')性能问题:处理超大矩阵(如 1000x1000)时,双重循环会很慢。可以改用pcolormesh结合PatchCollection优化,但需要重写绘制逻辑~颜色对比度:选择颜色映射时要考虑色盲友好性,plt.cm.viridis是一个不错的选择,或者使用seaborn的调色板:12import seaborn as snscmap = sns.color_palette("coolwarm", as_cmap=True)
-
一、前言在 Python 编程中,嵌套循环(Nested Loops) 是指在一个循环的内部再嵌套另一个循环。这种结构常用于处理多维数据结构(如二维数组、矩阵)、遍历组合数据、图形绘制等场景。虽然嵌套循环在逻辑上更复杂,但它是解决许多实际问题的关键工具之一。例如:遍历二维列表;打印星号图案(如金字塔、菱形);实现排序算法中的双重比较;检查多个集合之间的交集、并集;多线程任务调度等;本文将带你深入了解:嵌套循环的基本语法;for 与 while 的嵌套方式;常见应用场景;控制嵌套循环的技巧;常见误区与最佳实践;无论你是刚入门的新手,还是希望提升编程技巧的老手,这篇文章都将为你提供实用的知识点!二、什么是嵌套循环?嵌套循环是指在一个循环体内部包含另一个循环的结构。Python 中支持任意层级的嵌套,最常见的是两层嵌套(外层循环 + 内层循环),但也应避免过深嵌套,以免影响代码可读性。✅ 基本语法格式(以 for 为例):123for 外层变量 in 外层可迭代对象: for 内层变量 in 内层可迭代对象: # 循环体代码✅ 示例:打印九九乘法表1234for i in range(1, 10): for j in range(1, i+1): print(f"{j}x{i}={i*j}", end="\t") print()📌 输出:1x1=1 1x2=2 2x2=4 1x3=3 2x3=6 3x3=9...三、嵌套循环的工作机制嵌套循环的执行流程如下:外层循环执行一次;内层循环完整执行一轮;返回外层循环,继续下一次迭代;重复步骤 2~3,直到外层循环结束;📌 因此,如果外层循环执行 m 次,内层循环执行 n 次,则总共执行 m × n 次。四、常见的嵌套循环类型✅ 1. for 嵌套 for12345matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]for row in matrix: for item in row: print(item, end=" ") print()输出:1 2 3 4 5 6 7 8 9 📌 适用于二维列表或矩阵操作。✅ 2. for 嵌套 while12345for i in range(3): j = 0 while j < 3: print(f"i={i}, j={j}") j += 1📌 可根据需求灵活组合不同类型的循环。✅ 3. while 嵌套 while12345678i = 1while i <= 3: j = 1 while j <= i: print(j, end=" ") j += 1 print() i += 1输出:1 1 2 1 2 3 📌 适用于需要动态控制循环次数的情况。五、控制嵌套循环的关键字✅ 1. 使用 break 提前退出某一层循环12345for i in range(3): for j in range(3): if j == 1: break print(f"i={i}, j={j}")📌 只会跳出内层循环,外层仍继续执行。✅ 2. 使用标志位控制多层循环退出12345678found = Falsefor i in range(3): for j in range(3): if i == 1 and j == 1: found = True break if found: break📌 当你需要从多层循环中提前退出时,使用标志变量是推荐做法。✅ 3. 使用函数封装提高可读性12345678def find_target(): for i in range(3): for j in range(3): if i == 1 and j == 1: print("找到目标!") return find_target()📌 将嵌套循环封装成函数,通过 return 跳出所有循环,逻辑更清晰。六、实际开发中的常见应用场景✅ 1. 矩阵运算与图像处理1234image = [[(255, 0, 0), (0, 255, 0)], [(0, 0, 255), (255, 255, 0)]]for row in image: for pixel in row: print(pixel)📌 用于图像像素遍历、颜色转换等操作。✅ 2. 数据交叉匹配(如用户-商品推荐)123456users = ["Alice", "Bob"]products = ["iPhone", "MacBook"] for user in users: for product in products: print(f"{user} 推荐了 {product}")📌 模拟推荐系统中的简单交叉推荐逻辑。✅ 3. 打印图形(如三角形、菱形)12345n = 5for i in range(n): for j in range(i+1): print("*", end="") print()输出:***************📌 常用于初学者练习控制台绘图逻辑。✅ 4. 查找两个集合的交集12345678910set1 = {1, 2, 3}set2 = {2, 3, 4} common = []for a in set1: for b in set2: if a == b: common.append(a) print("交集:", common)📌 不使用内置方法,手动实现集合交集查找。七、注意事项与最佳实践建议说明✅ 避免过深嵌套(建议不超过 3 层)否则会影响代码可读性和维护性✅ 使用函数封装复杂逻辑提高复用性和模块化程度✅ 控制缩进一致性推荐统一使用 4 个空格缩进✅ 添加注释说明逻辑特别是在多重条件判断时✅ 使用列表推导式简化嵌套逻辑如 [x+y for x in A for y in B]八、总结对比表嵌套类型是否推荐适用场景for 嵌套 for✅ 强烈推荐遍历二维结构、生成组合for 嵌套 while✅ 推荐动态控制内层循环次数while 嵌套 while⚠️ 视情况而定条件驱动型嵌套逻辑多重嵌套(超过三层)❌ 不推荐应考虑重构或函数封装
-
1. 为啥要用多进程?先认清GILPython多线程为何没法加速CPU密集型任务?因为GIL(全局解释器锁):在主流的CPython解释器中,无论多少线程归根结底同时只有一个线程在执行Python字节码,严重影响CPU计算性能的并行。多进程机制完美绕开了GIL:每个进程拥有自己的Python解释器和内存空间,真正多核、多CPU并行执行,CPU密集型任务大大提速!2. Python多进程基础用法:multiprocessing库Python 内置标准库 multiprocessing,API与threading非常类似,上手容易。2.1 Proces介绍Process([group [, target [, name [, args [, kwargs]]]]])target 表示调用对象args 表示调用对象的位置参数元组kwargs 表示调用对象的字典name 为别名group 实质上不使用2.2 Hello,多进程1234567891011from multiprocessing import Processimport os def worker(): print('子进程PID:', os.getpid()) if __name__ == '__main__': p = Process(target=worker) p.start() p.join() print('主进程结束')注意! Windows下多进程要写在 if __name__ == '__main__': 保护块内,否则会无限递归启动进程。2.3 多进程并行计算1234567891011121314151617from multiprocessing import Processimport time def task(name): print(f'{name} 开始') time.sleep(2) print(f'{name} 结束') if __name__ == '__main__': proc_list = [] for i in range(3): p = Process(target=task, args=(f'进程{i+1}',)) p.start() proc_list.append(p) for p in proc_list: p.join() print('所有子进程结束')多个进程可并发分担任务,真正多核利用!2.4 子进程类实现(面向对象)12345678910111213141516171819import multiprocessingimport time class ClockProcess(multiprocessing.Process): def __init__(self, interval): multiprocessing.Process.__init__(self) self.interval = interval def run(self): n = 5 while n > 0: print("当前时间: {0}".format(time.ctime())) time.sleep(self.interval) n -= 1 if __name__ == '__main__': p = ClockProcess(3) p.start()3. 进阶:进程池批量并行(Process Pool)大量任务并发时,手动管理进程很麻烦,用Pool池自动分配和收集结果,极大提升效率!123456789101112from multiprocessing import Poolimport os, time def square(n): print('计算', n, '在进程', os.getpid()) time.sleep(1) return n * n if __name__ == '__main__': with Pool(processes=3) as pool: results = pool.map(square, range(5)) print('返回结果:', results)比循环创建 Process 简洁得多,还能自动分配CPU,每个子进程并发执行给定任务。4. 多进程间数据:通信与共享每个进程独立内存,不能像多线程那样直接共享变量多进程用队列(Queue)、管道(Pipe)或特殊共享对象实现4.1 用队列 Queue 通信(推荐)12345678910111213141516171819202122from multiprocessing import Process, Queue def producer(q): for i in range(5): q.put(i) q.put(None) # 发送结束标记 def consumer(q): while True: item = q.get() if item is None: break print('消费:', item) if __name__ == '__main__': q = Queue() p1 = Process(target=producer, args=(q,)) p2 = Process(target=consumer, args=(q,)) p1.start() p2.start() p1.join() p2.join()4.2 共享内存变量:Value 与 Array123456789101112131415from multiprocessing import Process, Value, Array def worker(val, arr): val.value += 10 for i in range(len(arr)): arr[i] *= 2 if __name__ == '__main__': num = Value('i', 5) # int类型共享变量 arr = Array('i', [1, 2, 3, 4]) # 数组 p = Process(target=worker, args=(num, arr)) p.start() p.join() print('num =', num.value) print('arr =', list(arr))5. 多进程安全:锁机制多进程也需防止竞争条件,通过 Lock/Manager 加锁同步。12345678910111213141516from multiprocessing import Process, Lock, Value def add(lock, counter): for _ in range(100000): with lock: counter.value += 1 if __name__ == '__main__': lock = Lock() counter = Value('i', 0) procs = [Process(target=add, args=(lock, counter)) for _ in range(4)] for p in procs: p.start() for p in procs: p.join() print('结果:', counter.value)6. 多进程vs多线程,该如何选?CPU密集(数值计算/图像处理/大数据科学):用多进程“跑满CPU”突破GILIO密集(爬虫/网络/磁盘/数据库交互):多线程即可,更省内存和切换开销
-
一、安装包1pip3 install JPype1二、使用步骤1、导入jpype模块2、python要调用的java的jar包路径3、获取jvm.dll的文件路径4、使用jpype开启虚拟机5、加载java类6、实例化类7、调用java方法8、关闭jvm三、代码演示12345678910111213141516171819202122import jpype#jar绝对包路径jar_path = '/Users/qinhaili/Desktop/MathUtil.jar'print(jar_path)#获取默认的 JVM 路径jvmPath = jpype.getDefaultJVMPath()#启动 JAVA 虚拟机jpype.startJVM(jvmPath,"-ea",f"-Djava.class.path={jar_path}")#环境测试代码,#成功输出说明安装环境成功jpype.java.lang.System.out.println( "hello world!" )#获取java类java_class = jpype.JClass('MathUtil')#类调用静态方法(类.方法名())result1 = java_class.sayHello()print(result1)#调用对象方法(类实例.方法名())#实话java类class_obj = java_class()result2 = class_obj.add(1,2)print(result2)#关闭JAVA虚拟机jpype.shutdownJVM()四、自己写一个jar包1234567891011121314class MathUtil{ public static String sayHello() { return "Hello How are you"; } public MathUtil() { } public int add(int a, int b) { return a + b; }}五、打包步骤1、编译得到.class文件1javac Hello.java2、创建jar包1jar cf xxxx.jar xxx.class3、打包必须得有java开发环境哈六、方法补充Python调用Java的jar包方式其实调用 Java 的 jar 包代码,和其他外部程序一样,可以使用 Python 的 subprocess 模块或者需要调用 Java 的 API(比如 Jython)来实现。下面是两个示例代码:使用 subprocess 模块:123456789101112131415import subprocess java_path = "/usr/bin/java" # Java 的路径jar_path = "path/to/your/jar/file.jar" # jar 包的路径 # 要执行的命令cmd = [java_path, "-jar", jar_path] # 执行proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)out, err = proc.communicate() # 打印输出和错误print(out.decode("utf-8"))print(err.decode("utf-8"))使用 Jython API:123456789101112131415from java.lang import Runtime jar_path = "path/to/your/jar/file.jar" # jar 包的路径 # 获取当前 JVM 实例jvm = Runtime.getRuntime() # 加载 jar 包jvm.load(jar_path) # 调用 jar 包中的方法result = jvm.callMethod("com.example.YourClass", "yourMethod", arg1, arg2) # 打印结果print(result)这里假设你已经安装好了 Jython。需要注意的是,这种方式需要在 Jython 中编写代码,而不是 Python,因为 Jython 是一种 Python 解释器,它能够解析 Java 代码。
-
1. Python在图像处理中的应用随着数字化时代的飞速发展,图像处理已经深入到日常生活的方方面面。Python作为一种广泛应用于数据科学、机器学习等领域的编程语言,也在图像处理领域表现出了其强大的优势。Python生态在图像处理方面拥有丰富的工具集,使得开发者能够在图像处理中实现复杂的功能。Python的图像处理功能不仅仅局限于传统的图像编辑和转换,它还能够实现图像识别、图像增强、机器视觉等多种高级功能。这得益于Python强大的库支持,其中最著名的包括Pillow、OpenCV、SciPy等。这些库提供了大量的图像处理功能,可以轻松实现图像的加载、保存、转换、滤镜、变形等操作。接下来的章节将会对Python在图像处理中的应用进行深入探讨,从Python生态概述、工具集介绍,到具体的图像处理库概览,将带领读者一步步了解Python在图像处理领域的强大能力。2. WebP格式的原理和优势2.1 WebP格式与传统格式对比WebP是Google在2010年推出的一种现代图像格式,旨在替代传统格式如JPEG、PNG和GIF。WebP提供了有损压缩和无损压缩两种模式,这意味着它可以在不同的使用场景下提供不同程度的图像质量与文件大小的平衡。WebP的有损压缩算法利用了先进的预测编码技术,在保持图片质量的同时,提供了比JPEG更小的文件尺寸。无损模式则采用LZ77派生的算法,加上后处理过滤器,使得文件大小显著小于PNG格式,同时保持相同的视觉质量。为了更深入地理解WebP的优势,我们可以看以下几点对比:文件大小 : WebP通常能在保持相同视觉质量的前提下,比JPEG和PNG格式提供更小的文件大小。这种更小的文件尺寸可以加速网页加载时间,从而提升用户体验。透明度 : 在支持透明度的图像格式中,WebP提供了比PNG更好的压缩效果。它通过Alpha通道进行透明度的处理,但在压缩性能上优于PNG。动画 : WebP同样支持动画格式,与GIF相比,WebP动画通常具有更小的文件大小和更高质量的视觉效果。2.2 WebP支持的特性解析WebP作为一种现代图像格式,它支持以下特性:透明度 : WebP支持无损和有损的透明度,可以在图片中使用alpha通道来表示透明度。动画 : WebP格式支持动画序列,适合用于创建动态图像。元数据 : 可以嵌入EXIF、XMP等元数据信息。色彩深度 : 支持最高24位的RGB颜色和8位的alpha通道。这种特性集的多样使得WebP在不同的应用场景中都能提供良好的支持。接下来,我们深入讨论WebP在不同领域的应用案例。3. 使用PIL/Pillow库处理图像转换3.1 PIL/Pillow库基础介绍3.1.1 PIL与Pillow库的简史Python Imaging Library(PIL)最初由Fredrik Lundh开发,是一个用于处理图像的强大库。然而,随着时间的推移,PIL的开发趋于停滞,社区中一个新的分支Pillow应运而生,由Alex Clark领导开发。Pillow旨在成为PIL的友好分支,兼容现有的PIL代码,并添加了新的功能。Pillow库修复了一些PIL中的bug,并提供了一些额外的特性,它得到了广泛的社区支持和更新,是当前活跃且推荐使用的图像处理库。3.1.2 PIL/Pillow库的主要功能PIL/Pillow库提供了全面的图像处理功能,包括但不限于: - 图像的创建、打开、修改以及保存。 - 支持多种图像格式,包括常见的JPEG、PNG、GIF、TIFF等。 - 提供了丰富的图像操作功能,如裁剪、合并、旋转、缩放等。 - 支持图像的插值算法,改善图像缩放质量。 - 提供图像处理滤镜,如模糊、锐化、边缘检测等。 - 支持透明度处理,可以处理带alpha通道的图像。Pillow库是Python图像处理的基石,无论是在科学计算还是日常的图像转换任务中,它都能提供高效的解决方案。3.2 PIL/Pillow进行图像操作的实践3.2.1 读取和写入图片使用Pillow库读取和写入图片是一个简单的过程。首先,需要安装Pillow库(如果尚未安装):1pip install Pillow然后,可以通过以下代码读取图片文件:1234from PIL import Image # 打开图片文件image = Image.open('path/to/your/image.jpg')写入图片到指定格式同样简单:12# 保存图片到新的文件格式image.save('path/to/your/save_location.png')3.2.2 图像格式转换的操作流程Pillow库可以轻松实现图像格式之间的转换。以下是一个将图片转换为PNG格式的示例代码:1234567from PIL import Image # 打开图片文件original_image = Image.open('path/to/your/image.jpg') # 将图片转换为PNG格式并保存original_image.convert('PNG').save('path/to/your/output_image.png')转换图像格式不仅包括文件扩展名的改变,同时也可能包括图像内部数据结构的转换。Pillow通过内置的转换器在不同格式间进行转换,并且保持了高质量的图像输出。3.2.3 图像处理实践Pillow库支持多种图像处理功能。以下是一个简单的图像处理流程,展示如何对一张图片进行裁剪操作:12345678910111213141516from PIL import Image # 打开图片文件image = Image.open('path/to/your/image.jpg') # 设置裁剪区域(左上角x,y坐标和宽度,高度)left = 100top = 100right = 300bottom = 300 # 执行裁剪操作cropped_image = image.crop((left, top, right, bottom)) # 保存裁剪后的图片cropped_image.save('path/to/your/cropped_image.png')通过Pillow库,还可以进行更复杂的图像处理任务,例如图像的旋转、缩放、颜色调整、应用滤镜效果等。这些功能的实现都是通过Pillow库提供的丰富接口完成的,具体用法请参阅官方文档。以上章节内容充分展示了PIL/Pillow库在图像处理中的基础应用和实践操作。作为Python中图像处理的重要工具,Pillow库不仅方便易用,而且功能全面,能够满足从初学者到高级用户的各类图像处理需求。4. 利用multiprocessing库进行并行处理4.1 multiprocessing库概述4.1.1 并行处理与Python的多进程模型在现代软件开发中,尤其是图像处理等计算密集型任务中,能够高效地利用多核处理器的计算资源是提高程序性能的关键。Python在处理多线程任务时受限于全局解释器锁(Global Interpreter Lock, GIL),使得多线程并不能在CPU密集型任务中实现真正的并行执行。然而,Python的多进程模型提供了一个绕过GIL的解决方案,使得程序能够在多个处理器核心上并行运行。Python通过`multiprocessing`库提供了一个接口来创建多个进程,从而实现并行处理。每个进程拥有自己的Python解释器和内存空间,因此不受GIL的限制。这种机制特别适用于那些可以并行处理的算法,比如图像处理任务中的图像转换、图像效果应用等。4.1.2 multiprocessing库的主要组件`multiprocessing`库的主要组件包括`Process`类,用于创建新的进程,`Queue`和`Pipe`等用于进程间通信(IPC),以及`Pool`类,它提供了一个方便的方法来创建进程池,可以并发地执行指定数量的任务。这些组件可以被用来构建出高度可定制的并行处理解决方案,不仅适用于图像处理,还能扩展到其他需要高并行度的场景。4.2 并行处理图像转换的优势与挑战4.2.1 并行处理的性能优势在进行图像转换这样的CPU密集型任务时,使用`multiprocessing`库能显著提高执行效率。通过将图像分割为多个部分,并将这些部分分配给不同的进程来处理,可以充分利用多核处理器的优势。例如,在将大量的JPEG图像转换为WebP格式的场景中,如果顺序执行,每个转换操作都需要等待前一个操作完成后才能继续,这会导致CPU资源的浪费。而并行处理可以同时启动多个转换任务,缩短了整体的执行时间,提高了效率。4.2.2 遇到的问题和解决方案然而,并行处理也带来了新的挑战,如进程间同步、内存管理、任务调度等。这些都需要妥善的解决方案来确保系统的稳定性和效率。例如,在并行处理图像转换时,可能会遇到输出文件命名冲突的问题。多个进程可能同时尝试写入同一个文件名的输出文件,导致数据覆盖或损坏。一种解决方案是使用`multiprocessing`提供的`Lock`或`Semaphore`来控制对共享资源的访问,确保每个进程在写入文件前能获得一个锁。12345678910111213141516from multiprocessing import Process, Lock def convert_image(input_image, output_image, lock): with lock: # 在这里执行图像转换操作 pass if __name__ == '__main__': lock = Lock() processes = [] for image in image_list: p = Process(target=convert_image, args=(image, output_image, lock)) processes.append(p) p.start() for p in processes: p.join()在此代码示例中,每个进程在执行图像转换前会尝试获取一个锁。只有当一个进程成功获取锁后,它才能执行图像转换操作。这可以防止多个进程同时写入同一个输出文件的问题。在下一章节中,我们将深入探讨如何利用 multiprocessing 库,结合具体的需求,实现批量转换图片为WebP格式的Python脚本。这将涉及到图像读取、格式判断、并行处理以及错误处理等多个方面,展示并行处理在实际应用中的强大优势。5. 批量转换图片为WebP格式的Python脚本实现5.1 脚本需求分析和设计方案5.1.1 确定脚本功能和目标在本节中,我们将深入了解如何实现一个Python脚本,用于批量将图片文件转换为WebP格式。WebP格式因其高压缩比和良好的图像质量特性,成为了图像文件大小优化的理想选择。脚本的主要目标是为用户提供一个便捷的解决方案,通过简单地运行脚本,即可将文件夹中的所有或指定图片转换为WebP格式,同时保留或优化图像质量,并处理可能出现的错误情况。具体来说,脚本的功能应该包括:自动识别并处理目标文件夹中的图片文件。支持多种常见的图像格式作为输入,如JPEG、PNG等。提供转换质量的选项,允许用户根据需要调整输出的图像质量。实现多线程或并行处理,以加速转换过程。输出转换结果,并提供对错误和异常情况的处理反馈。5.1.2 设计方案的细节和选择设计这样一个脚本涉及到多个决策点。首先,选择合适的图像处理库是核心环节。根据我们的需求,Pillow(PIL的一个分支)是一个不错的选择,因为它是Python中最常用的图像处理库之一,并且对WebP格式提供支持。其次,为了实现并行处理,我们可以使用Python的 multiprocessing 模块。这样可以在多核心的CPU上并行处理图像转换任务,大大提高处理效率。接下来,我们需要考虑脚本的命令行界面(CLI)。使用像 argparse 这样的标准库可以帮助我们构建用户友好的命令行参数解析功能。脚本应该能够处理如下参数:输入目录:脚本将在此目录中查找图片文件。输出目录:转换后的图片将被保存在这个目录下。转换质量:一个可选参数,允许用户指定输出图像的质量。并发数:一个可选参数,指定用于并行处理的进程数量。5.2 脚本的核心代码解析5.2.1 图片读取和格式判断在开始编写脚本之前,我们要先了解如何使用Pillow库来读取和判断图片格式。代码块如下:1234567891011121314151617from PIL import Imageimport os def get_image_files(directory): """ 获取给定目录下的所有图片文件。 参数: directory: str - 图片文件所在的目录 返回: list - 包含图片文件的路径列表 """ supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.gif') image_files = [] for filename in os.listdir(directory): if filename.lower().endswith(supported_formats): image_files.append(os.path.join(directory, filename)) return image_files上述函数 get_image_files 遍历指定目录,筛选出所有支持的图片格式文件,并将它们的路径添加到列表中返回。它使用了标准库 os 来列出目录中的所有文件,并通过文件扩展名来判断文件是否为支持的图片格式。5.2.2 并行处理与输出控制并行处理可以通过 multiprocessing 模块实现。以下是一个基本的并行处理流程的代码示例:123456789101112131415161718192021222324252627282930313233343536import multiprocessingfrom concurrent.futures import ProcessPoolExecutor def convert_image_to_webp(filepath, quality, output_dir): """ 将单个图片转换为WebP格式并保存。 参数: filepath: str - 输入图片文件的路径 quality: int - WebP转换的质量设置 output_dir: str - 输出目录的路径 """ try: image = Image.open(filepath) if not os.path.exists(output_dir): os.makedirs(output_dir) webp_filename = os.path.join(output_dir, os.path.basename(filepath) + '.webp') image.save(webp_filename, format='webp', quality=quality) except Exception as e: print(f"Error converting file {filepath}: {e}") def process_images_parallel(image_paths, quality, output_dir, workers=4): """ 并行处理图片转换。 参数: image_paths: list - 图片文件路径列表 quality: int - WebP转换的质量设置 output_dir: str - 输出目录的路径 workers: int - 并行处理的工作进程数量 """ with ProcessPoolExecutor(max_workers=workers) as executor: for _ in executor.map(convert_image_to_webp, image_paths, [quality]*len(image_paths), [output_dir]*len(image_paths)): pass # 示例调用image_files = get_image_files('path/to/images')process_images_parallel(image_files, quality=85, output_dir='path/to/output', workers=multiprocessing.cpu_count())此代码段首先定义了 convert_image_to_webp 函数,用于打开一张图片、保存为WebP格式。然后定义了 process_images_parallel 函数,它接受图片路径列表、质量设置、输出目录和工作进程数量,使用 ProcessPoolExecutor 来并行执行转换任务。 workers 参数默认设置为CPU核心数,以达到最优的并行效率。5.2.3 错误处理和异常管理在进行文件操作时,错误处理是必须要考虑的环节。脚本中应增加适当的异常处理逻辑来捕获并处理可能出现的错误。例如:12345678try: # ...执行文件操作代码...except FileNotFoundError: print("The provided path does not exist.")except IOError as e: print(f"File I/O error: {e}")except Exception as e: print(f"An unexpected error occurred: {e}")在 convert_image_to_webp 函数中,我们已经使用了一个简单的异常处理机制。不过,在更复杂的脚本中,可能需要更详细的错误日志记录,并且在主函数中维护一个错误日志文件。这将允许用户在转换大量文件时能够追踪哪些文件遇到了问题,同时不会中断整个脚本的运行。此外,对于图像转换质量的设置, convert_image_to_webp 函数中的 quality 参数可以提供给用户一定的控制权。用户可以根据需求和对图像质量与文件大小的权衡来指定该参数,影响输出文件的质量。通过以上步骤的深入分析和代码实现,我们已经完成了批量转换图片为WebP格式的Python脚本的核心功能和异常处理策略。在接下来的章节中,我们将讨论如何对脚本进行错误处理的扩展以及如何通过命令行参数来增加脚本的灵活性和可用性。6. 错误处理和命令行参数解析的潜在扩展在开发实际应用软件的过程中,错误处理和命令行参数解析是两个不可或缺的环节。它们不仅可以提升程序的健壮性,也极大地增强了用户的使用体验。本章节将深入探讨错误处理的重要性和实践方法,同时,解析命令行参数的技巧,这对于脚本的扩展性及用户友好性都至关重要。6.1 错误处理的重要性与实践方法在进行Python脚本开发时,正确处理错误是保证程序正常运行的关键。错误处理不当可能导致程序崩溃或数据丢失,因此,合理地使用异常处理机制能够提升程序的健壮性。6.1.1 错误类型和处理策略在Python中,常见的错误类型包括语法错误(SyntaxError)、运行时错误(如KeyError, IOError, ValueError等),以及更高级别的业务逻辑错误。合理地分类并处理这些错误是开发过程中的重要环节。语法错误 通常在代码执行之前就被编译器捕捉到,因此对这类错误的处理主要在于预防。运行时错误 需要通过try-except块来捕捉和处理。例如,在文件操作中:12345try: with open('non_existent_file.txt', 'r') as file: content = file.read()except IOError as e: print(f"An error occurred while reading the file: {e}")业务逻辑错误 往往需要自定义异常,通过定义异常类来处理特定的错误情况。6.1.2 实践中的错误处理代码示例下面的示例代码展示了如何处理在批量转换图片时可能会遇到的不同类型的错误:12345678910111213141516171819202122232425262728import sysimport osfrom PIL import Image def convert_to_webp(src_dir, dest_dir): if not os.path.isdir(src_dir): raise ValueError("Source directory does not exist") if not os.path.isdir(dest_dir): os.makedirs(dest_dir) for filename in os.listdir(src_dir): src_file = os.path.join(src_dir, filename) if not os.path.isfile(src_file): print(f"Skipping {src_file}: Not a regular file") continue try: img = Image.open(src_file) img.save(os.path.join(dest_dir, f"{filename}.webp"), "WEBP") except IOError as e: print(f"Could not convert {src_file}: {e}") try: convert_to_webp(sys.argv[1], sys.argv[2])except IndexError as e: print("Please provide the source and destination directories as arguments")except ValueError as e: print(f"Value error: {e}")上述代码在执行图片转换操作时,通过异常处理机制来捕获可能发生的错误,从而避免程序中断。6.2 命令行参数解析的深入应用命令行参数解析工具可以让用户通过命令行界面与Python脚本进行交互,提高了脚本的可用性和灵活性。6.2.1 命令行参数解析工具的选择Python提供了多种工具来解析命令行参数,如内置的 argparse 模块,第三方的 click 库等。 argparse 是Python标准库的一部分,使用广泛,功能强大,足以应对大多数需求。6.2.2 参数解析在脚本扩展性中的作用使用命令行参数解析器不仅可以提升用户体验,还可以使得脚本更加灵活和可扩展。例如,参数可以用来控制脚本的执行方式,指定输出格式,甚至激活特定的功能模块。6.2.3 高级参数解析示例与技巧下面代码利用 argparse 模块来增强脚本的命令行接口,通过定义不同的参数选项来控制输出和行为:12345678910111213141516171819202122import argparseimport osimport webbrowser def create_parser(): parser = argparse.ArgumentParser(description="Batch convert images to WebP format.") parser.add_argument('source', type=str, help='Path to the directory containing images.') parser.add_argument('destination', type=str, help='Path to the directory where converted images will be saved.') parser.add_argument('-o', '--open', action='store_true', help='Open the destination folder after conversion.') return parser def main(): parser = create_parser() args = parser.parse_args() # ... (省略转换图片的代码) ... if args.open: webbrowser.open(args.destination) if __name__ == '__main__': main()
-
一、Ray 核心概念1. Ray 集群Ray 集群由一个头节点(Head Node)和多个工作节点(Worker Nodes)组成。头节点负责协调任务分配和资源管理,而工作节点则执行具体的计算任务。Ray 集群可以部署在本地机器、云平台或 Kubernetes 上。2. 任务(Tasks)任务是 Ray 中最基本的执行单元。通过 @ray.remote 装饰器,可以将普通函数转换为远程任务。任务可以在集群中的任何节点上并行执行。12345678910111213import ray ray.init() # 初始化 Ray 集群 @ray.remotedef add(x, y): return x + y # 提交任务result_id = add.remote(1, 2)# 获取任务结果result = ray.get(result_id)print(result) # 输出: 33. ActorActor 是 Ray 中的有状态对象,可以包含状态和方法。与任务不同,Actor 的方法调用会在同一个 Actor 实例上执行,从而维护状态。1234567891011121314@ray.remoteclass Counter: def __init__(self): self.value = 0 def increment(self): self.value += 1 return self.value # 创建 Actor 实例counter = Counter.remote()# 调用 Actor 方法for _ in range(5): print(ray.get(counter.increment.remote())) # 输出: 1, 2, 3, 4, 54. 对象存储(Object Store)Ray 提供了分布式对象存储系统,用于在集群中共享数据。数据可以通过 ray.put() 存储,并通过 ray.get() 检索。1234data = [1, 2, 3, 4, 5]data_id = ray.put(data) # 将数据存储到对象存储retrieved_data = ray.get(data_id) # 从对象存储检索数据print(retrieved_data) # 输出: [1, 2, 3, 4, 5]二、Ray 高级特性1. 资源管理Ray 允许为任务和 Actor 指定资源需求(如 CPU、GPU 等)。集群调度器会根据资源请求分配任务。1234@ray.remote(num_gpus=1) # 请求 1 个 GPUdef train_model(data): # 模型训练代码 pass2. 容错与弹性Ray 提供了容错机制,当节点故障时,任务可以重新调度到其他节点执行。此外,Ray 支持动态扩展集群,根据负载自动添加或删除节点。3. 与机器学习库集成Ray 提供了多个专用库,用于简化机器学习工作流:Ray Tune:超参数调优库,支持并行化搜索。Ray Train:分布式训练库,支持多种深度学习框架(如 TensorFlow、PyTorch)。Ray RLlib:强化学习库,支持分布式训练。Ray Serve:模型服务库,支持快速部署和扩展。三、Ray 应用场景1. 并行计算Ray 可以将计算密集型任务拆分为多个子任务,并行执行,从而显著加速计算。123456789101112131415import rayimport time ray.init() @ray.remotedef compute_heavy_task(i): time.sleep(1) # 模拟耗时计算 return i * i # 提交多个任务result_ids = [compute_heavy_task.remote(i) for i in range(10)]# 获取结果results = ray.get(result_ids)print(results) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]2. 分布式机器学习Ray 可以与 PyTorch 或 TensorFlow 结合,实现分布式模型训练。123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657import rayimport torchimport torch.nn as nnimport torch.optim as optimfrom torch.utils.data import DataLoader, TensorDataset ray.init() # 定义简单模型class SimpleModel(nn.Module): def __init__(self): super().__init__() self.linear = nn.Linear(10, 1) def forward(self, x): return self.linear(x) # 模拟数据X = torch.randn(1000, 10)y = torch.randn(1000, 1)dataset = TensorDataset(X, y)dataloader = DataLoader(dataset, batch_size=32) # 分布式训练函数@ray.remotedef train_epoch(model_weight_id, dataloader_id, epoch): model_weight = ray.get(model_weight_id) model = SimpleModel() model.load_state_dict(model_weight) criterion = nn.MSELoss() optimizer = optim.SGD(model.parameters(), lr=0.01) dataloader = ray.get(dataloader_id) for batch_X, batch_y in dataloader: optimizer.zero_grad() outputs = model(batch_X) loss = criterion(outputs, batch_y) loss.backward() optimizer.step() # 返回更新后的模型权重 updated_weight = model.state_dict() return updated_weight # 初始化模型权重model = SimpleModel()initial_weight = model.state_dict()weight_id = ray.put(initial_weight)dataloader_id = ray.put(dataloader) # 提交多个训练任务for epoch in range(5): weight_id = train_epoch.remote(weight_id, dataloader_id, epoch) # 获取最终模型权重final_weight = ray.get(weight_id)print("Training completed!")3. 实时流处理Ray 可以与 Kafka 等流处理系统结合,实现实时数据处理。12345678910111213141516171819202122232425262728293031323334353637383940import rayfrom confluent_kafka import Producer, Consumer ray.init() @ray.remoteclass KafkaProducerActor: def __init__(self, bootstrap_servers): self.producer = Producer({'bootstrap.servers': bootstrap_servers}) def produce(self, topic, message): self.producer.produce(topic, value=message) self.producer.flush() @ray.remoteclass KafkaConsumerActor: def __init__(self, bootstrap_servers, group_id, topic): self.consumer = Consumer({ 'bootstrap.servers': bootstrap_servers, 'group.id': group_id, 'auto.offset.reset': 'earliest' }) self.consumer.subscribe([topic]) def consume(self): msg = self.consumer.poll(1.0) if msg is not None and msg.error() is None: return msg.value().decode('utf-8') return None # 创建生产者和消费者 Actorproducer_actor = KafkaProducerActor.remote('localhost:9092')consumer_actor = KafkaConsumerActor.remote('localhost:9092', 'test-group', 'test-topic') # 生产消息ray.get(producer_actor.produce.remote('test-topic', b'Hello, Ray!')) # 消费消息message = ray.get(consumer_actor.consume.remote())print(f"Received message: {message}") # 输出: Received message: Hello, Ray!四、Ray 部署与扩展1. 本地部署在本地机器上运行 Ray 集群非常简单,只需调用 ray.init() 即可。123import ray ray.init() # 初始化本地 Ray 集群2. 云部署Ray 支持在 AWS、GCP、Azure 等云平台上部署。可以通过 Ray 的自动伸缩功能,根据负载动态调整集群规模。3. Kubernetes 部署Ray 提供了 Kubernetes 操作符(Ray Operator),可以方便地在 Kubernetes 集群上部署和管理 Ray 集群。五、Ray 最佳实践合理分配资源:为任务和 Actor 指定适当的资源需求,避免资源争用。使用 Actor 管理状态:对于需要维护状态的任务,使用 Actor 而不是普通任务。优化数据传输:尽量减少节点间的数据传输,利用 Ray 的对象存储共享数据。监控与调试:使用 Ray 的内置工具监控集群状态和任务执行情况。
-
1. 使用 logging 模块12345678910111213141516import multiprocessingimport logging def worker(queue): logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger('worker') logger.debug(f"Worker {multiprocessing.current_process().name} started") # 工作代码... if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger('main') queue = multiprocessing.Queue() p = multiprocessing.Process(target=worker, args=(queue,)) p.start() p.join()2. 使用远程调试器使用 pdb 的替代方案 - rpdb1234567891011# 安装: pip install rpdbimport rpdb def worker(): rpdb.set_trace() # 会在26163端口启动调试器 # 工作代码... if __name__ == '__main__': p = multiprocessing.Process(target=worker) p.start() p.join()然后可以使用 telnet localhost 26163 连接进行调试。3. 使用 multiprocessing.get_context()123456789101112import multiprocessingimport pdb def worker(): pdb.set_trace() # 每个子进程都会在这里暂停 # 工作代码...if __name__ == '__main__': ctx = multiprocessing.get_context('spawn') p = ctx.Process(target=worker) p.start() p.join()4. 使用 IDE 的远程调试功能大多数现代 IDE (PyCharm, VSCode) 都支持远程调试多进程程序:在 IDE 中配置远程调试在子进程代码中添加调试器连接代码启动主程序并连接调试器5. 打印调试信息12345678910111213import multiprocessingimport sys def worker(lock): with lock: print(f"Worker {multiprocessing.current_process().name} started", file=sys.stderr) # 工作代码... if __name__ == '__main__': lock = multiprocessing.Lock() p = multiprocessing.Process(target=worker, args=(lock,)) p.start() p.join()6. 使用 faulthandler 捕获崩溃信息1234567891011import faulthandlerimport multiprocessing def worker(): # 工作代码... if __name__ == '__main__': faulthandler.enable(file=open('crash.log', 'w')) p = multiprocessing.Process(target=worker) p.start() p.join()7. 常见问题排查问题1: 子进程不执行代码确保所有代码都在 if __name__ == '__main__': 块中检查是否使用了正确的进程启动方法问题2: 死锁检查是否正确使用了锁和其他同步原语考虑使用 multiprocessing.Manager() 管理共享状态问题3: 资源泄漏确保所有进程都正确关闭了文件、网络连接等资源使用 with 语句管理资源8. 高级技巧使用 traceback 捕获异常1234567891011121314import multiprocessingimport tracebackimport sys def worker(): try: # 工作代码... except Exception: traceback.print_exc(file=sys.stderr) if __name__ == '__main__': p = multiprocessing.Process(target=worker) p.start() p.join()使用 multiprocessing.log_to_stderr()123456789101112131415import multiprocessingimport logging multiprocessing.log_to_stderr()logger = multiprocessing.get_logger()logger.setLevel(logging.DEBUG) def worker(): logger.debug("Worker started") # 工作代码... if __name__ == '__main__': p = multiprocessing.Process(target=worker) p.start() p.join()
-
1. 服务器管理SSH 远程操作1.Paramiko作用:基于 Python 的 SSHv2 协议库,支持远程执行命令、上传下载文件。示例:连接服务器执行命令:12345678910111213import paramiko # 创建 SSH 客户端client = paramiko.SSHClient()client.set_missing_host_key_policy(paramiko.AutoAddPolicy())client.connect(hostname='your_server_ip', username='user', password='pass') # 执行命令stdin, stdout, stderr = client.exec_command('ls -l /tmp')print(stdout.read().decode()) # 关闭连接client.close()2.Fabric作用:简化 SSH 操作的库,通过 fabfile.py 定义任务。示例:批量重启服务:12345678from fabric import Connectiondef restart_nginx(): # 连接到服务器 c = Connection('user@server_ip') # 执行命令 c.run('sudo systemctl restart nginx') print("Nginx restarted!")2. 配置管理2.1 Ansible核心概念:基于 YAML 的 Playbook 定义自动化任务,无需在目标服务器安装 Agent。示例 Playbook(deploy_web.yml):123456789101112131415- hosts: webservers # 目标服务器分组 become: yes # 使用 sudo 权限 tasks: - name: Install Nginx apt: name: nginx state: present - name: Copy Config File copy: src: ./nginx.conf dest: /etc/nginx/nginx.conf - name: Start Nginx service: name: nginx state: restarted执行 Playbook:1ansible-playbook -i inventory.ini deploy_web.yml2.2 SaltStack特点:基于消息队列的分布式配置管理工具,适合大规模集群。示例:通过 Salt 模块安装软件:1salt '*' pkg.install nginx3. 监控与告警3.1 系统监控psutil作用:获取系统资源使用情况(CPU、内存、磁盘、网络)。示例:监控 CPU 使用率:12345import psutil cpu_usage = psutil.cpu_percent(interval=1)mem_usage = psutil.virtual_memory().percentprint(f"CPU: {cpu_usage}%, Memory: {mem_usage}%")Prometheus + GrafanaPrometheus Client:通过 Python 客户端上报自定义指标。123456789from prometheus_client import start_http_server, Gauge # 定义指标CPU_GAUGE = Gauge('cpu_usage', 'Current CPU usage in percent') # 启动 HTTP 服务暴露指标start_http_server(8000)while True: CPU_GAUGE.set(psutil.cpu_percent())Grafana:可视化 Prometheus 数据,生成实时监控面板。3.2 日志监控ELK Stack(Elasticsearch + Logstash + Kibana)Python 集成:使用 python-elasticsearch 库写入日志到 Elasticsearch:123456789from elasticsearch import Elasticsearch es = Elasticsearch(['http://localhost:9200'])log_data = { "timestamp": "2023-10-01T12:00:00", "level": "ERROR", "message": "Disk space low on /dev/sda1"}es.index(index="app_logs", document=log_data)4. 自动化部署4.1 CI/CD 集成Jenkins + Python场景:通过 Jenkins Pipeline 调用 Python 脚本完成构建、测试、部署。示例 Jenkinsfile:123456789101112pipeline { agent any stages { stage('Deploy') { steps { script { sh 'python deploy.py --env production' } } } }}4.2 Docker 管理Docker SDK for Python作用:通过 Python 控制 Docker 容器生命周期。示例:启动一个 Nginx 容器:123456789import dockerclient = docker.from_env()container = client.containers.run( "nginx:latest", detach=True, ports={'80/tcp': 8080})print(f"Container ID: {container.id}")5. 日志分析与处理Loguru作用:简化日志记录,支持颜色输出、文件轮转。示例:1234from loguru import logger logger.add("app.log", rotation="100 MB") # 日志文件轮转logger.info("Service started successfully")Apache Airflow场景:编排复杂的 ETL 任务或定时日志分析任务。示例 DAG:12345678910111213from airflow import DAGfrom airflow.operators.python_operator import PythonOperatorfrom datetime import datetime def analyze_logs(): print("Analyzing logs...") dag = DAG('log_analysis', start_date=datetime(2023, 1, 1))task = PythonOperator( task_id='analyze_logs', python_callable=analyze_logs, dag=dag)6. 自动化运维最佳实践模块化设计:将重复操作封装为函数或类(如连接服务器、执行命令)。错误处理:捕获异常并记录日志,避免脚本因单点故障中断。1234try: response = requests.get('http://api.example.com', timeout=5)except requests.exceptions.Timeout: logger.error("API request timed out")安全性:使用 SSH 密钥代替密码,敏感信息存储在环境变量或加密文件中。定时任务:结合 cron 或 APScheduler 实现定时执行。1234567from apscheduler.schedulers.blocking import BlockingSchedulerscheduler = BlockingScheduler()@scheduler.scheduled_job('interval', minutes=30) def health_check(): print("Performing health check...")scheduler.start()
-
已识别语言为python,但在运行时 提示 要求新增配置项,且只能 配置为java?
-
打开项目的时候,出现了这个错误选择对应conda环境后,状态栏成功加载到conda的python但是在编辑区里面,发现并没有加载到对应conda的python的对应的库。PySide6库已经是安装好了,但是IDE显示是没有安装,也没有任何补全。conda的python环境加载了个寂寞。选择创建环境,就显示没有找到全局解释器。
StarDarkMonarch
发表于2025-06-06 17:55:03
2025-06-06 17:55:03
最后回复
StarDarkMonarch
2025-07-17 10:09:31
119 4 -
Python应用篇_在线课程_华为云开发者学堂_云计算培训-华为云在学习过程中,playsound报错:D:\SoftWare\Anaconda\python.exe D:\MusicPlayer\utils\action2.py D:\MusicPlayer\utils\action2.py:168: SyntaxWarning: invalid escape sequence '\M' file="D:\MusicPlayer\source\qianqian.mp3" Error 277 for command: open "D:\MusicPlayer\source\qianqian.mp3" 初始化 MCI 时发生问题。 Error 263 for command: close "D:\MusicPlayer\source\qianqian.mp3" 指定的设备未打开,或不被 MCI 所识别。Failed to close the file: "D:\MusicPlayer\source\qianqian.mp3"Traceback (most recent call last): File "D:\MusicPlayer\utils\action2.py", line 169, in <module> playsound(file) File "C:\Users\BHY\AppData\Roaming\Python\Python312\site-packages\playsound.py", line 72, in _playsoundWin winCommand(u'open {}'.format(sound)) File "C:\Users\BHY\AppData\Roaming\Python\Python312\site-packages\playsound.py", line 64, in winCommand raise PlaysoundException(exceptionMessage)playsound.PlaysoundException: Error 277 for command: open "D:\MusicPlayer\source\qianqian.mp3" 初始化 MCI 时发生问题。Process finished with exit code 1代码与教案的相同Python应用篇_在线课程_华为云开发者学堂_云计算培训-华为云
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签