PyInstaller打包的Python可执行文件闪退问题求助
沟渠流量/水位计算程序打包后终端闪退问题排查
我用Python编写了一款可根据流量q计算水位y、或根据水位y计算流量q的沟渠计算程序,通过PyInstaller的--onefile参数打包为可执行文件后,运行时终端仅短暂弹出就立即关闭,以下是原程序代码:
# this calculates the y given the q and the q when given y # the inner if is for the forward movement (y to q) # the outer if is for reverse movement (q to y) import math import sympy from sympy import * from math import * def velocity (n,r,s): #computes the velocity of the flow return (1/n)*(r**(2/3))*(sqrt(s)) print ("select the desired choice between options one and two.") print ("for determining the discharge,q (type 1)") print ("for determining the height of the water level in a trench,y (type 2)") choice = input ("type desired calculation: ") if choice == ("1"): print("trench shapes include triangular, rectangular and trapezoidal.") shape = input("enter shape of trench: ") # triangular if shape == ("triangular"): y = float(input("enter the height of the water level,y: ")) x = float(input("enter the deviation of the slope,x: ")) s = float(input("enter value of the bottom slope,S: ")) n = float(input("enter value of mannings coeficient: ")) r = (x*y)/(2* sqrt(1 + (x**2))) A = x*(y**2) v = velocity(n,r,s) q = A * v print("the discharge q is " + str(round(q,2))) #rectangular elif shape == ("rectangular"): b = float(input("enter length of base of trench,b: ")) y = float(input("enter height of water in trench,y: ")) s = float(input("enter value of the bottom slope,S: ")) n = float(input("enter value of mannings coeficient,n: ")) R = (b*y)/(b + 2*y) #hydraulic radius A = b*y #area v = velocity(n,R,s) q = A*v print("the discharge q is " + str(round(q,2))) #trapezoidal elif shape == ("trapezoidal") : b = float(input("enter the length of the base,b: ")) y = float(input("enter the height of the water level,y: ")) x = float(input("enter the deviation of the slope,x: ")) s = float(input("enter value of the bottom slope,s: ")) n = float(input("enter value of mannings coeficient,n: ")) R = ((b + x*y) *y)/(b + 2*y*sqrt((1 + (x**2)))) #hydraulic radius A = (b + x*y)*(y) #area v = velocity(n,R,s) q = A*v print ("the discharge q is " + str(round(q ,2))) else : print ("Please enter available trench shape.") elif choice == ("2"): print("trench shapes include triangular, rectangular and trapezoidal.") shape = input("enter shape of trench: ") # triangular if shape == ("triangular"): q = float(input("enter the value of the discharge,q: ")) x = float(input("enter the value of the incline slope,x: ")) s = float(input("enter the value of the bottom slope,s: ")) n = float(input("enter the value of mannings coefficient,n: ")) y = (4 * ((q * n) ** 3) * (1 + x ** 2)) / ((x ** 5) * (s ** (3 / 2))) y = y ** (1 / 8) print("the height of the water in the trench,y, is: " + str(round(y, 2))) # rectangular elif shape == ("rectangular"): q = float(input("enter the value of the discharge,q: ")) b = float(input("enter length of base of the trench,b: ")) s = float(input("enter the value of the bottom slope,s: ")) n = float(input("enter the value of mannings coefficient,n: ")) y = Symbol('y', postive=True) eq = Eq(q, (1 / n) * (((b * y) / (b + 2 * y)) ** (2 / 3)) * (sqrt(s) * (b * y))) m = solve(eq, y) m1 = m[0] print("the height of the water in the trench,y, is " + str(round(m1, 2))) # trapezoidal elif shape == ("trapezoidal"): q = float(input("enter the value of the discharge,q: ")) b = float(input("enter length of base of the trench,b: ")) x = float(input("enter the value of the incline slope,x: ")) s = float(input("enter the value of the bottom slope,s: ")) n = float(input("enter the value of mannings coefficient,n: ")) y = Symbol('y') eq = Eq(q, (1 / n) * (((y * (b + x * y)) / (b + 2 * y * sqrt(1 + x ** 2))) ** (2 / 3)) * (sqrt(s)) * (y * (b + x * y))) m = nsolve(eq, y, 0) print("the height of the water in the trench,y, is " + str(round(m,2))) else: print("Please enter available trench shape.") else: print ("Please type 1 or 2.")
问题原因与解决方法
1. 核心问题点
- 无异常捕获:输入非法值(如非数字)、计算错误(如除以0、开负数根号)会直接崩溃,终端闪退且无错误提示
- 依赖打包不全:SymPy库在
--onefile模式下可能未被正确包含,导致运行时找不到依赖 - 运行后直接退出:计算完成后无暂停逻辑,用户来不及查看结果终端就关闭
2. 修正后的代码(中文适配+错误处理+防闪退)
# 根据q计算y或根据y计算q的沟渠流量/水位计算程序 import math import sympy from sympy import * from math import * def velocity(n, r, s): # 计算流速 return (1/n) * (r**(2/3)) * (sqrt(s)) print("请选择计算类型:") print("1 - 计算流量q") print("2 - 计算沟渠水位y") try: choice = input("输入选择(1/2):") if choice == "1": print("沟渠形状包括:三角形、矩形、梯形") shape = input("输入沟渠形状:").strip().lower() # 三角形沟渠 if shape == "三角形": y = float(input("输入水位高度y:")) x = float(input("输入边坡系数x:")) s = float(input("输入底坡S:")) n = float(input("输入曼宁系数n:")) r = (x*y) / (2 * sqrt(1 + x**2)) A = x * (y**2) v = velocity(n, r, s) q = A * v print(f"流量q为:{round(q, 2)}") # 矩形沟渠 elif shape == "矩形": b = float(input("输入沟渠底宽b:")) y = float(input("输入水位高度y:")) s = float(input("输入底坡S:")) n = float(input("输入曼宁系数n:")) R = (b*y) / (b + 2*y) # 水力半径 A = b*y # 过水面积 v = velocity(n, R, s) q = A * v print(f"流量q为:{round(q, 2)}") # 梯形沟渠 elif shape == "梯形": b = float(input("输入沟渠底宽b:")) y = float(input("输入水位高度y:")) x = float(input("输入边坡系数x:")) s = float(input("输入底坡S:")) n = float(input("输入曼宁系数n:")) R = ((b + x*y) * y) / (b + 2*y*sqrt(1 + x**2)) # 水力半径 A = (b + x*y) * y # 过水面积 v = velocity(n, R, s) q = A * v print(f"流量q为:{round(q, 2)}") else: print("请输入有效的沟渠形状:三角形、矩形、梯形") elif choice == "2": print("沟渠形状包括:三角形、矩形、梯形") shape = input("输入沟渠形状:").strip().lower() # 三角形沟渠 if shape == "三角形": q = float(input("输入流量q:")) x = float(input("输入边坡系数x:")) s = float(input("输入底坡S:")) n = float(input("输入曼宁系数n:")) y = (4 * ((q * n)**3) * (1 + x**2)) / ((x**5) * (s**(3/2))) y = y ** (1/8) print(f"沟渠水位y为:{round(y, 2)}") # 矩形沟渠 elif shape == "矩形": q = float(input("输入流量q:")) b = float(input("输入沟渠底宽b:")) s = float(input("输入底坡S:")) n = float(input("输入曼宁系数n:")) y = Symbol('y', positive=True) # 修正拼写错误postive→positive eq = Eq(q, (1/n) * (((b*y)/(b + 2*y))**(2/3)) * (sqrt(s) * (b*y))) m = solve(eq, y) m1 = m[0] print(f"沟渠水位y为:{round(m1, 2)}") # 梯形沟渠 elif shape == "梯形": q = float(input("输入流量q:")) b = float(input("输入沟渠底宽b:")) x = float(input("输入边坡系数x:")) s = float(input("输入底坡S:")) n = float(input("输入曼宁系数n:")) y = Symbol('y', positive=True) eq = Eq(q, (1/n) * (((y*(b + x*y))/(b + 2*y*sqrt(1 + x**2)))**(2/3)) * sqrt(s) * (y*(b + x*y))) m = nsolve(eq, y, 1) # 初始值设为1,避免0导致的计算错误 print(f"沟渠水位y为:{round(m, 2)}") else: print("请输入有效的沟渠形状:三角形、矩形、梯形") else: print("请输入1或2选择计算类型") except Exception as e: print(f"运行出错:{str(e)}") # 运行结束后暂停,避免终端闪退 input("按回车键退出...")
3. 打包命令优化
使用以下命令打包,确保SymPy依赖被正确包含:
pyinstaller --onefile --hidden-import sympy your_script_name.py
如果仍有问题,添加--console参数强制显示终端,方便查看错误信息:
pyinstaller --onefile --console --hidden-import sympy your_script_name.py
内容的提问来源于stack exchange,提问作者Msafiri Hillary
相关产品推荐
相关产品推荐

