
前言「用 Python 写网页」这句话不同的人理解差别很大。一种理解是「用 Python 生成 HTML」那还是得懂标签、懂表单、懂一点点前端另一种理解是「我只会写 Python 函数但我想让别人在浏览器里点几下、看到结果」。PyWebIO 走的是后一条路。先说清楚它的定位避免用错场景PyWebIO 是一个第三方库需要单独安装它把浏览器当成一个「输入输出终端」你用input()那样的函数拿数据、用put_text()那样的函数显示结果交互流程按你写代码的顺序推进。它适合内部小工具、报表、数据核对脚本的快速上线不适合做面向公众的正式站点——没有 SEO 意义上的页面结构也不适合承载复杂的页面布局和前端交互。还要纠正一个常见说法把 PyWebIO 说成「不用写任何代码就能做网站」是不准确的。你依然要写代码只是写的是顺序执行的 Python 代码而不是 HTML/JS/CSS 三件套。它的价值在于把「做一个有输入框、有按钮、有结果的页面」这件事从跨技术栈的问题变成了写函数的问题。本文讲清楚三件事它的核心想法是什么、输入输出控件怎么写、什么时候该用它、什么时候不该用。文中涉及的具体接口签名以 PyWebIO 官方文档为准版本差异也请以官方文档为准。一、核心想法把网页交互写成顺序执行的脚本传统网页开发是「事件驱动」的你绑定一个回调用户点按钮时回调被触发你要自己管理「现在页面处于哪种状态」。PyWebIO 换了个模型你的函数从头到尾顺序执行遇到输入函数就停下来等用户输入拿到值之后继续往下走。这就是它最像命令行程序的地方——整个交互流程就是你代码的缩进顺序。你的函数开始↓input(请输入姓名) ← 浏览器显示一个输入框函数在这里等↓用户填完点提交拿到 name 变量↓put_text(你好 name) ← 浏览器显示一行文字↓函数结束这样做的好处是一个原本要用「表单提交 后端路由 状态管理」才能完成的小工具现在就是一个带几个缩进层级的函数。代价是它不适合做「页面上有十几个互相关联的控件、每改一个就局部刷新」这种复杂界面。二、输入、输出与按钮输入控件输入类函数都在pywebio.input下共同点是调用即阻塞返回值就是用户填的内容。# 适用于 Python 3.8需先安装 PyWebIO接口以官方文档为准from pywebio.input import input, select, checkbox, radio, textarea, NUMBERname input(请输入姓名)age input(请输入年龄, typeNUMBER) # NUMBER 让返回值是数字city select(所在城市, options[北京, 上海, 广州])hobbies checkbox(兴趣爱好, options[读书, 跑步, 音乐]) # 返回列表level radio(熟练程度, options[入门, 熟练])remark textarea(备注, rows3)几个要点input()的type决定控件形态与返回值类型。默认是TEXT字符串传NUMBER时返回数字其它类型常量请对照官方文档。select默认是单选返回选中的那一项multipleTrue时返回列表。checkbox返回的是列表radio返回的是单个值不要搞反。所有输入函数都支持validate参数传一个函数进去做校验返回错误字符串表示校验不通过、页面会提示。# 适用于 Python 3.8需先安装 PyWebIO接口以官方文档为准from pywebio.input import input, NUMBERdef check_age(value):if value 0 or value 150:return 年龄要在 0 到 150 之间return Noneage input(年龄, typeNUMBER, validatecheck_age)validate返回None表示通过返回字符串则把这句话显示给用户。校验逻辑放在这里比拿到值之后再自己判断要友好得多——页面不会因为一个不合法的输入就整个中断。输出控件输出类函数都在pywebio.output下顾名思义都是往页面上「放」东西。# 适用于 Python 3.8需先安装 PyWebIO接口以官方文档为准from pywebio.output import put_text, put_markdown, put_table, put_successput_text(处理完成) # 普通文本put_markdown(## 统计结果\n\n共 3 条记录) # 渲染 Markdownput_table([[姓名, 分数],[小明, 92],[小红, 88],])put_success(全部通过)put_table接收一个二维列表第一行可以当表头。单元格里也可以放别的输出对象比如put_markdown(...)的返回值这在要做「表格里带链接/加粗」时很有用。按钮按钮用put_buttons输出并绑定一个点击回调# 适用于 Python 3.8需先安装 PyWebIO接口以官方文档为准from pywebio.output import put_buttons, put_textdef on_click(choice):put_text(你点了 choice)put_buttons([确认, 取消], onclickon_click)buttons是按钮列表onclick是回调函数回调会收到被点击按钮对应的值。注意输出函数是往里放内容不会阻塞。如果你需要「等用户点一下再继续」用的是pywebio.input.actions那才是一个阻塞的输入函数。三、把它跑起来写完之后用一个启动函数把应用挂到本地端口上。PyWebIO 支持多种后端默认的启动方式就够用了# 适用于 Python 3.8需先安装 PyWebIO接口以官方文档为准from pywebio import start_serverdef main():name input(请输入姓名)put_text(你好 name)if __name__ __main__:start_server(main, port8080, debugTrue)启动后浏览器打开本机 8080 端口就能看到页面。port参数建议显式传不要依赖默认值——不同后端的默认端口并不一致这一点对照官方文档最稳妥。四、什么时候该用、什么时候不该用场景适合 PyWebIO 吗原因给同事写个数据查询小工具适合输入 → 查询 → 展示结果一条直线把一段分析脚本变成网页适合不用重构逻辑加几个输入输出即可生成一份可交互的报表适合put_table直接出表够用面向公众的官网、博客不适合缺少页面结构与 SEO 所需的静态化能力复杂的前端交互与动画不适合顺序执行模型天然不擅长频繁的局部更新高并发对外服务不适合定位是内部工具部署与安全加固要另想办法一句话总结选型你的交互流程能用一条「从上到下」的流程图描述清楚就用它一旦流程图里出现大量往回指的箭头就该换方案了。常见坑点1. 把checkbox的返回值当字符串用❌if checkbox(爱好, options[读书]): ...然后拿去做字符串拼接。 ✅checkbox返回列表比如[读书]拼接时要, .join(hobbies)。2. 以为put_buttons会阻塞等待❌put_buttons([确认], onclickcb)之后立刻假设用户已经点过了。 ✅put_buttons只是把按钮画上去不阻塞需要「等点击」请用pywebio.input.actions。3. 把校验写在拿到值之后❌ 先input(年龄)再用if判断、手动抛异常中断整个流程。 ✅ 用validate参数返回错误字符串让页面就地提示流程不中断。4. 忘记安装依赖❌ 直接from pywebio.input import input报模块找不到。 ✅ PyWebIO 是第三方库先按官方文档安装再运行脚本。5. 用它做面向公众的正式站点❌ 把 PyWebIO 应用当作官网主站对外发布。 ✅ 它定位是内部小工具正式站点请用常规 Web 框架配套模板、静态资源与安全配置。6. 依赖默认端口❌start_server(main)不传port换了后端就不知道访问哪个端口。 ✅ 显式写start_server(main, port8080)并核对官方文档里该后端支持的参数。7. 拿input的返回值直接当数字运算❌age input(年龄)之后写age 1字符串加整数直接报错。 ✅ 声明typeNUMBER或自己显式转换并处理转换失败的输入。8. 在输出里拼 HTML 字符串❌ 为了让文字加粗在put_text里塞标签字符串。 ✅ 用put_markdown(**加粗**)表达富文本要输出原生 HTML 用put_html并意识到它不会做转义处理。总结概念一句话记住执行模型函数顺序执行遇到输入函数就阻塞等用户输入pywebio.input下的函数返回值即用户输入输出pywebio.output下的put_xxx调用即上屏、不阻塞按钮put_buttons绑定回调要阻塞等待用actions定位内部工具、报表、脚本网页化不是公众站点PyWebIO 的初体验往往很顺把一个已有的 Python 脚本加几行输入输出十分钟就能变成一个别人点得动的网页。但请记住它的边界——它是「把脚本搬上网页」的捷径不是「做网站」的替代品。选型时先问自己交互流程是不是一条直线答案就清楚了。