Python WAR打包上传场景下简化多个try-except语句的方案咨询
Python代码优雅实现方案
核心优化思路
- 去掉冗余的逐步骤
try-except:业务步骤是强依赖关系,前序步骤失败后后续逻辑无法正常执行,统一在外层按异常类型捕获即可,避免重复代码 - 封装重复的命令执行逻辑:把subprocess调用、输出打印、异常处理抽成公共函数,减少重复代码
- 修复原代码隐含bug:比如
glob.glob返回列表需要判空后再取值、路径拼接的变量未定义问题、异常块中调用未赋值变量的问题 - 优先使用Python原生库替代shell调用:用
requests代替curl上传文件,更符合Python开发习惯,也更容易处理异常
优化后代码
import shutil import subprocess import os import glob import traceback import requests from requests.auth import HTTPBasicAuth # 封装公共的命令执行函数,统一处理输出和异常 def run_command(cmd, shell=False): try: res = subprocess.run( cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell, text=True # 直接返回字符串,无需手动decode ) print(res.stdout) return res except subprocess.CalledProcessError as e: print(f"命令执行失败,退出码:{e.returncode}\n错误信息:{e.stderr}") raise # 抛出异常让外层统一处理后续逻辑 def my_function(path_a, path_b, tmp_dir): war_file_name = "" file_version = "" try: # 1. 复制文件到临时目录 shutil.copy(path_a, tmp_dir) shutil.copy(path_b, tmp_dir) # 2. 生成war包,替换为你实际的war生成命令 run_command(["your", "war", "gen", "command"]) # 3. 处理路径、提取文件名和版本,替换FILE_PATH/ARTIFACT_DATE/FILE_WO_EXTENSION为实际变量 output_folder = os.path.join("/tmp/dir/work", FILE_PATH, ARTIFACT_DATE, FILE_WO_EXTENSION) war_list = glob.glob(os.path.join(output_folder, "*.war")) if not war_list: raise FileNotFoundError(f"在{output_folder}下未找到war文件") war_file_path = war_list[0] war_file_name = os.path.basename(war_file_path) # 可根据实际文件名规则调整版本号提取逻辑,比如用正则匹配 file_version = war_file_name.replace(".war", "") # 4. 重命名为tgz(如不需要可删除该步骤) tgz_file_path = war_file_path.rsplit(".", 1)[0] + ".tgz" os.rename(war_file_path, tgz_file_path) upload_file_path = tgz_file_path # 5. 上传到仓库,敏感信息建议从环境变量读取不要硬编码 with open(upload_file_path, "rb") as f: resp = requests.put( "你的仓库上传地址", auth=HTTPBasicAuth("用户名", "密码"), data=f ) resp.raise_for_status() print("上传成功") return war_file_name, file_version except Exception as e: traceback.print_exc() # 可在此处添加失败回滚逻辑,比如清理临时文件 raise # 若不需要调用方感知失败可注释该语句
额外说明
- 如果业务允许某个步骤失败后继续执行,可以单独给对应步骤加
try-except,不需要所有步骤都加 - 文件名和版本号的提取逻辑可以根据实际命名规则调整,比如用正则匹配更规范的版本号格式
- 若必须使用curl上传,可直接调用封装好的
run_command函数执行curl命令即可
内容的提问来源于stack exchange,提问作者Chel MS
相关产品推荐
相关产品推荐

