你写完了最后一行代码,有代程序在终端里跑得挺欢。出软然后呢?有代双击那个.py文件,它弹出一个黑框,出软一闪而过。有代发给朋友,出软对方回一句“打不开”。有代这就是出软代码和软件之间那条看不见的沟。
我见过太多人卡在这一步。有代去年有个做数据分析的出软同事,写了三千行Python脚本处理公司报表,有代每次运行都要打开PyCharm,出软点那个绿色三角。有代他问我怎么把它变成“一个东西”,出软让财务部的有代人自己点。我告诉他:你得先承认,你手里的不是软件,是一份说明书。软件是别人不需要看说明书就能用的东西。
把代码变成软件,第一件事是决定它长什么样。命令行工具也算软件,比如ffmpeg,但普通人不会用。你要么给它一个窗口,要么给它一个浏览器页面。Python有个内置的tkinter,丑,但五分钟能出一个带按钮的窗口。把print换成label.config(text=...),把input()换成entry.get()。代码逻辑几乎没动,但财务部的人能看懂了。
更省事的路线是Web。用Flask或者FastAPI把你原来的函数包一层路由。以前def process_data(file):,现在上面加个@app.route('/upload')。前端随便写个HTML表单,或者用Streamlit——那东西连HTML都不用写,st.file_uploader直接生成上传按钮。我试过把一个图像处理脚本改成Streamlit应用,从开始到部署到内网服务器,花了四十分钟。原来的代码一行没改,只是外面套了个st.button('运行')。
但能跑起来只是开始。真正的坑在依赖。你电脑上pip install的那些包,别人电脑上没有。用PyInstaller打包成.exe?杀毒软件会报毒,而且打出来的文件两百兆起步。用Docker?财务部的人不知道Docker是什么。最笨也最稳的办法:写一个requirements.txt,再写一个启动.bat,里面就一行python main.py。然后教对方装Python。听起来很蠢,但比打包成exe之后发现缺了个dll要省心。
界面和分发解决了,还有数据。你的代码可能读./data.csv,但用户把软件装到D盘,那个相对路径就找不到了。用os.path.dirname(os.path.abspath(__file__))把路径钉死在代码文件旁边。用户上传的文件别乱存,放tempfile.gettempdir()里,用完就删。这些细节不写进代码,软件就是一颗定时炸弹。
我自己的习惯是:任何超过五十行的脚本,只要有人要第二次运行,我就给它加个界面。哪怕只是tkinter的一个按钮。因为“帮我跑一下”这句话,说三次就会变成“你自己怎么不学一下”。而一个带按钮的窗口,能把这句话堵回去。
最后说个反常识的:别追求完美。你不需要安装程序、不需要图标、不需要版本号。一个run.py加一个启动.sh,扔到共享文件夹里,就是软件。我见过一个运维写的备份工具,界面就是终端里print出来的一个菜单,输入1备份,输入2恢复。用了三年,没人抱怨。因为它解决了问题,而且没让人装任何东西。
代码是你和机器对话。软件是你替别人和机器对话。中间隔着的不是技术,是“别人不想知道技术”这件事。