第一个应用跑起来 — 环境、工作流,和那个密码检查器¶
这一章讲三件事: 把开发环境搭对(Git、编辑器、虚拟环境); Streamlit 特有的「保存 → 浏览器里重跑」开发循环; 以及第一个完整应用——密码检查器——从逻辑流到每一行代码。 读完你能自己把一个 Streamlit 应用从
streamlit run跑到浏览器里, 并且看懂代码里每个st.函数在屏幕上对应什么。
1. 这一章讲什么¶
第 01 章告诉你 Streamlit 值得学;这一章让你真的跑起来。 顺序是:先装(Python 3.9 以上,pip install streamlit)1, 再谈三个影响你今后每一天效率的环境决定2, 然后看一遍开发工作流的全貌3,最后从零写一个密码检查器应用, 再改它、看它热更新、最后杀掉服务器4。
附录(Installing Python and Streamlit)是安装细节的官方出处:
macOS 和 Windows 两条路径、怎么查现有 Python 版本(python --version,
附录特意提醒 -V 是大写)5。安装本身没有概念难度,我们不再单独拆一章,
需要的细节都在这一章的原文地图里。
2. 顶层全景:你按下的每个键去了哪里¶
先建立整张图,后面每一节都是图上的一个框:
你的代码编辑器 你的终端 浏览器
┌──────────────┐ streamlit run app.py ┌──────────────────┐
│ 写 app.py │ ───────────────────────▶ │ localhost:8501 │
│ 保存(Ctrl-S)│ 启动 Streamlit 服务器 │ 看到应用,点按钮 │
└──────────────┘ │ └────────▲─────────┘
▲ │ 监视文件变化 │ 发请求
│ ▼ │
│ 文件一变,浏览器右上角 │
└─────────── 出现「Rerun / Always Rerun」───────┘
图说:编辑器是你的,终端里的服务器是 Streamlit 的,浏览器是你的应用的。
三个窗口,一条循环。
三个要点:(1) streamlit run 启动的是一台服务器——一个常驻进程,
你的终端窗口就是它的家;关终端 = 杀服务器6。
(2) 服务器会监视你的代码文件,保存后浏览器里出现重跑提示7。
(3) 浏览器和服务器说的地址是 http://localhost:8501——
localhost 意思是「我这台电脑」,8501 是 Streamlit 的默认端口号8。
3. 核心原理(一):环境三件套,各自解决一个什么麻烦¶
这三个工具都不是 Streamlit 特有的,但这本书把它们放在第一章讲,因为它们决定了你之后的开发体验。
Git:代码的时光机。 版本控制(Git 是今天最流行的实现)做的事用一句话说: 给代码的每次变动留一份可回去的历史9。为什么非要它:你会改主意、会试三种设计再挑一个、 半年后看不懂自己当时为什么这么写——Git 让每个「当时」都能回去、都留有说明10。 书里给的定位很务实:第 5.2 节有「够部署用的最小 Git」,想学深去 Atlassian 的教程11。
编辑器:PyCharm 或 VS Code。 Streamlit 应用本质是文本文件,记事本也能写; 但「代码编辑器」提供语法高亮、错误检查、跳转,效率完全是两个量级12。 书里对 IDE(集成开发环境,装上就全配好的那种)和插件化编辑器的分野说得很清楚: PyCharm 是 JetBrains 做的 Python 专用 IDE,开箱即全,Community 版免费13; VS Code 本体轻巧、靠插件生态变全,配好了能做付费版 PyCharm 的一切,还免费14。
这里有一处值得单独记的作者判断:这一节写成之后,AI 优先的编程工具 (Codex、Claude Code、Cursor)已经流行起来,但作者建议学习阶段仍用普通 IDE—— AI 工具日常很强,学基础时会让你跳过本该亲手做的那部分15。
虚拟环境:每个项目一间独立病房。 问题是这样的:不同项目依赖的库版本常常冲突, 给项目 A 升级一个库,项目 B 莫名其故地坏了16。虚拟环境就是给每个项目配一个隔离的 Python 副本,各自的库互不见面17。你会听到 venv、pipenv、pyenv、poetry 这些名字—— 它们是同一类工具的不同实现,选一个用即可18。
为什么这三件排在写代码之前¶
书里有一句很容易被滑过去的话:环境选择「很大程度上是个人偏好」, 但长期会显著影响你的效率19。翻译一下:工具本身没有对错,但「从没配好过环境的人」 和「环境顺手的人」之间的差距,半年后会大到不成比例。这一章花篇幅讲三件非 Streamlit 的事, 是刻意安排——它不想你卡在「我的库装哪去了」上。
4. 核心原理(二):Streamlit 的开发循环——和其他编程不一样的一步¶
普通 Python 脚本的循环是:写 → 跑(python app.py)→ 看结果 → 改。
Streamlit 的循环多了一跳,因为应用是「活」在浏览器里的:
① 写代码 ② 保存 ③ streamlit run app.py(只跑一次!)
④ 在浏览器里试 ⑤ 回编辑器改 ⑥ 保存
⑦ 回浏览器,右上角点 Rerun(或 Always Rerun) ⑧ 回到 ④
图说:关键在 ⑦——不用重跑 streamlit run,服务器一直在,你要的只是「让脚本再跑一遍」。
「Always Rerun」(旧版本界面叫 Run on Save)打开后,保存即自动重跑,改代码到看效果的 延迟缩到一秒级20;代价是页面整个刷新,改动小的时候不容易看出哪里变了, 所以也可以在设置里关掉、手动点21。还有一条边界情况:改的不是 .py 文件 (应用依赖的文本文件、数据库),偶尔需要杀掉服务器重来——见第 7 节22。
5. 核心原理(三):密码检查器——第一个应用,逐行走一遍¶
这是本章主线例子。应用的逻辑流(书里 figure 2.5 那张图,我们复述成文字):
用户在一行输入框里输入密码,点「Check password」
│
▼
程序手里有一张「规则表」(4 条规则),逐条拿密码去检查
│
▼
每条规则得到一个结果:PASS 或 FAIL
│
▼
屏幕上逐条显示:过的打绿框,不过的打红框
图说:输入 → 检查 → 上色,一条直线,没有回头路。
完整代码(照原书 listing 2.1,注释从简):
import streamlit as st
conditions = {
'More than 8 characters': lambda pw: len(pw) > 8,
'At least one uppercase letter':
lambda pw: any(char.isupper() for char in pw),
'At least one lowercase letter':
lambda pw: any(char.islower() for char in pw),
'At least one special character':
lambda pw: any(char in ",.!?@#$%^&*()-_+=|\\/:;<>~" for char in pw),
}
def get_password_properties(password):
return {cond: check(password) for cond, check in conditions.items()}
st.title("Password Checker")
password_input = st.text_input("Enter your password", type="password")
if st.button("Check password"):
if password_input:
properties = get_password_properties(password_input)
for condition, passes in properties.items():
if passes:
st.success(f' ✔ Pass: {condition}')
else:
st.error(f' ✖ Fail: {condition}')
else:
st.write("Please enter a password.")
逐行走一遍,拿一个具体输入当标本。 设用户输入 Streamlit1!:
import streamlit as st——引入库,st是全行业通用的别名,你听到的「st 点什么东西」 说的就是 Streamlit 元素23。conditions = {...}——一个字典:键是规则的名字(人读的句子), 值是一个 lambda(匿名的单行函数):给它密码,它返回这条规则过没过24。 四条规则分别是:长度 > 8、有大写、有小写、含特殊字符。get_password_properties(password)——把密码逐条送进四个 lambda, 返回一个新字典{规则名: True/False};这个写法叫字典推导式25。st.title("Password Checker")——屏幕上出现大标题。注意:它是无条件执行的, 每次运行都画一次。password_input = st.text_input("Enter your password", type="password")—— 屏幕上出现一个输入框,type="password"让输入以圆点遮蔽显示26。 关键:用户输入的文本这一刻就存在password_input里了;这一轮脚本往下走时, 用的就是这个值。if st.button("Check password"):——屏幕上出现按钮。这是全书第一个会咬人的句子: 没点按钮时,这个条件为假,if 里的代码根本不执行;点了按钮、脚本重跑的这一轮, 它才为真27。按钮的「状态」不是存在某个事件回调里,而是就是这一次运行里的一个布尔值。- 假设这一轮按钮是被点的:if 里先确认密码非空,再调
get_password_properties, 然后对四个结果逐条st.success(绿框)/st.error(红框)28。 对我们的输入Streamlit1!:长度 11 > 8 ✔、有S✔、有小写 ✔、有!✔——四条全绿。 换成abc:长度 ✖、无大写 ✖、有小写 ✔、无特殊字符 ✖——两绿两红。 - 若输入框是空的,
st.write("Please enter a password.")提示先输入29。
这段代码里藏着的三个「第一次」¶
- 第一次看见「脚本即界面」:界面上有什么,完全由这一次脚本执行经过哪些
st.调用决定; 顺序、有无,全是代码的顺序和条件。 - 第一次看见「按钮 = 一次重跑里的条件」:它没有事件监听,而是「这次运行按钮恰好被按下了」。 第 04 章会告诉你这个设计为什么有力、什么时候反噬。
- 第一次看见 Streamlit 的调试入口:应用不对,先看「这一轮脚本走到哪了」—— 因为界面就是执行轨迹本身。
6. 跑起来、改它、杀掉它——一条完整的生命周期¶
跑。 在文件所在目录执行 streamlit run password_checker.py;
终端出现 Local URL: http://localhost:8501(端口号也可能是 8502,占用时会自动换)30。
浏览器没自动打开的话,手动敲那个地址;换个浏览器(Chrome 最稳)也常是解药31。
改。 书里示范的修改:给 conditions 加第五条规则(至少一位数字),
再给按钮文案加个感叹号32。保存后,浏览器右上角立刻出现「source file has changed」
的提示,附 Rerun / Always Rerun 两个选项33。点 Rerun,按钮变成「Check password!」,
数字检查生效。any(char.isdigit() for char in pw) 就是新规则的全部代码34。
杀。 服务器活着,靠的是你那个终端窗口。Ctrl-C(或关窗口)之后,
浏览器里的应用立刻「死」给你看:按钮变灰、右上角转「CONNECTING」35。
再 streamlit run 一次就复活——而且旧的浏览器标签也会跟着活过来,
因为它重新连上了新服务器36。记住这个体感:界面不能脱离服务器存在,
服务器才是应用的本体,浏览器只是它的投影。
7. 作者的判断与证据¶
判断:学习阶段别用 AI 编程工具。 依据是作者观察到的行业变化 (Codex、Claude Code、Cursor 兴起),论断形式是建议而非论证37。 我们认可方向,但补一句书里没说的:这条建议对「学 Streamlit」适用, 对「用 Streamlit 干活」未必——两者目标不同。
判断:先写个差不多完整的版本再第一次运行,而不是边写边看。 作者明说这是个人偏好:早早看到界面会让人忍不住抠外观,忘了先把逻辑写完38。 这类「工匠偏好」在全书反复出现,读的时候当成「一种被验证过的口味」而非定律。
证据强度备注: 环境三件套(Git/编辑器/虚拟环境)是行业标准实践,证据充分; 「Always Rerun 更顺滑」「Chrome 问题最少」是经验之谈,无对照实验; 密码检查器的逐行走读是可直接复现的操作,你自己跑一遍即可验证。
8. 边界与局限¶
- 版本门槛会过期。 书里说 Python 3.9+、推荐 3.11+39;附录写 Streamlit 要 3.10+40。 这两处本身就不一致(以你的 Streamlit 版本官方说明为准),而且这类下限几乎必然随时间上移。
- 安装细节属于「快照」:具体下载页面、按钮位置,出版后就会漂移;要装就去看当时的官方文档,别照书点。
- 工作流一节假定你在本机开发。 远程开发环境(云 IDE、容器里写代码)的循环不一样, 这一章没有覆盖;第 12 章的 Docker 会部分补上「环境长什么样」的图景。
- 虚拟环境只讲了「为什么」和「有哪些选择」,没有给完整操作流。 venv 的具体命令、 poetry 的用法都不在正文里——这是有意的留白,但对零基础读者来说可能正好卡在门口。
- 「杀掉服务器」那一节的「CONNECTING」现象,是第 04 章执行模型最好的预告片; 如果当时觉得「为什么界面不能自己活着」,恭喜你——你已经摸到了那个问题。
判断(我们的,不是书里的): 这一章看起来是「安装教程」,实际上是全书 心智模型的第一次落地:界面 = 脚本的一次执行;按钮 = 这一次执行里的条件; 服务器 = 应用的本体。密码检查器之所以选得妙,是因为它小到可以完整装进脑子, 又恰好把三个模型全用上。相比之下,环境三件套是任何 Python 书都有的标准内容, 不是这本书的独特贡献。 如果错,会错在: 如果读者已经熟悉 Git/虚拟环境,这一章的增量几乎全在 第 5–6 节;把整章当必读对老手的性价比低——但它的存在是为「半技术读者」 这个明确受众服务的,这个取舍本身没有错。
9. 可带走的¶
streamlit run app.py启动的是服务器,终端窗口就是它的命;Ctrl-C = 杀服务器 = 浏览器里界面变灰。- 开发循环的灵魂是 Rerun/Always Rerun:服务器常驻,你只是在反复「让它再跑一遍」。
localhost:8501:localhost = 本机,8501 = 默认端口;局域网里别人可用 Network URL 访问。- 界面元素按代码顺序出现;
if st.button(...)里没有回调,按钮状态就是这一轮运行里的布尔值。 st.text_input(type="password")遮蔽输入;st.success/st.error是语义化颜色的消息框;st.write是万能输出。- 「规则表 = 字典,规则 = lambda」是组织检查逻辑的好样板:加规则就是加一行字典。
- Git 当时光机用,虚拟环境当隔离病房用——两个比喻背后的机制(提交历史 / 独立解释器)值得各花一小时搞实。
- 学习阶段用普通 IDE,别用 AI 代写——至少第一个应用要自己敲。
- 改了非 .py 的依赖(数据文件、库版本)而界面没变,第一反应是重启服务器。
- 浏览器打不开应用时的排查序:手动敲 Local URL → 升级浏览器 → 换 Chrome。
10. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 安装:Python 3.9+ 与 pip install streamlit | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:30搜「pip install streamlit」) |
| Git 是「代码的时光机」 | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:46搜「time machine」) |
| 学习阶段不建议 AI 优先工具 | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:74搜「Codex」) |
| PyCharm / VS Code 对比 | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:65搜「Code editors」) |
| 虚拟环境解决依赖冲突 | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:98搜「Virtual environments」) |
| streamlit hello 自带演示 | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:394搜「streamlit hello」) |
| 开发工作流九步(figure 2.4) | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:141搜「development workflow」) |
| 密码检查器完整代码(listing 2.1) | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:260搜「Listing 2.1」) |
| lambda 与字典推导式解释 | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:321搜「lambdas」) |
| st.button 放进 if 的第一处伏笔 | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:354搜「some interesting nuances」) |
| localhost:8501 与 Network URL | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:404搜「Local URL」) |
| 改代码后 Rerun / Always Rerun | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:456搜「Always Rerun」) |
| 关闭服务器后的 CONNECTING 现象 | 2 Getting started with Streamlit | text/11-ch02-2-getting-started-with-streamlit.txt:484搜「CONNECTING」) |
| 附录:查 Python 版本、-V 大写 | Appendix Installing Python and Streamlit | text/22-apx-i-appendix-installing-python-and-streamlit.txt:27搜「case-sensitive」) |
-
出处:「2 Getting started with Streamlit」第 17–21 段(
text/11-ch02-2-getting-started-with-streamlit.txt:30,搜「pip install streamlit」)。原文:装 3.9+ 的 Python(作者推荐 3.11+),然后 pip install streamlit。 ↩ -
出处:「2 Getting started with Streamlit」第 22–26 段(
text/11-ch02-2-getting-started-with-streamlit.txt:13,搜「three key workflow considerations」)。 ↩ -
出处:「2 Getting started with Streamlit」第 141–145 段(
text/11-ch02-2-getting-started-with-streamlit.txt:142,搜「iterative process」)。 ↩ -
出处:「2 Getting started with Streamlit」第 196–199 段(
text/11-ch02-2-getting-started-with-streamlit.txt:196,搜「Building your first app」)。 ↩ -
出处:「Appendix Installing Python and Streamlit」第 9–24 段(
text/22-apx-i-appendix-installing-python-and-streamlit.txt:20,搜「python --version」)。「-V is case-sensitive」在该文件第 21 段。 ↩ -
出处:「2 Getting started with Streamlit」第 477–485 段(
text/11-ch02-2-getting-started-with-streamlit.txt:479,搜「serves」)。原文:这个终端窗口就是 serve 你的应用的 Streamlit 服务器所在;Ctrl-C 关闭后按钮禁用、界面显示 CONNECTING。 ↩ -
出处:「2 Getting started with Streamlit」第 460–461 段(
text/11-ch02-2-getting-started-with-streamlit.txt:460,搜「monitors your app file」)。 ↩ -
出处:「2 Getting started with Streamlit」第 410–414 段(
text/11-ch02-2-getting-started-with-streamlit.txt:410,搜「localhost」)。原文解释 localhost 意为「你这台电脑」,端口可能是 8502 等。 ↩ -
出处:「2 Getting started with Streamlit」第 42–48 段(
text/11-ch02-2-getting-started-with-streamlit.txt:46,搜「time machine for your code」)。 ↩ -
出处:「2 Getting started with Streamlit」第 49–56 段(
text/11-ch02-2-getting-started-with-streamlit.txt:50,搜「go back in time」)。 ↩ -
出处:「2 Getting started with Streamlit」第 60–63 段(
text/11-ch02-2-getting-started-with-streamlit.txt:62,搜「Atlassian」)。 ↩ -
出处:「2 Getting started with Streamlit」第 65–71 段(
text/11-ch02-2-getting-started-with-streamlit.txt:68,搜「Integrated Development Environment」)。 ↩ -
出处:「2 Getting started with Streamlit」第 78–85 段(
text/11-ch02-2-getting-started-with-streamlit.txt:84,搜「Community Edition」)。 ↩ -
出处:「2 Getting started with Streamlit」第 86–92 段(
text/11-ch02-2-getting-started-with-streamlit.txt:89,搜「ecosystem of plugins」)。 ↩ -
出处:「2 Getting started with Streamlit」第 72–76 段(
text/11-ch02-2-getting-started-with-streamlit.txt:73,搜「AI-first tools」)。原文:推荐学习过程中坚持用普通的非 AI IDE。 ↩ -
出处:「2 Getting started with Streamlit」第 98–103 段(
text/11-ch02-2-getting-started-with-streamlit.txt:102,搜「updating a library for one project breaks another」)。 ↩ -
出处:「2 Getting started with Streamlit」第 108–111 段(
text/11-ch02-2-getting-started-with-streamlit.txt:109,搜「isolated instance of Python」)。 ↩ -
出处:「2 Getting started with Streamlit」第 114–115 段(
text/11-ch02-2-getting-started-with-streamlit.txt:115,搜「venv, pipenv, pyenv, poetry」)。 ↩ -
出处:「2 Getting started with Streamlit」第 23–25 段(
text/11-ch02-2-getting-started-with-streamlit.txt:35,搜「largely a matter of preference」)。 ↩ -
出处:「2 Getting started with Streamlit」第 465–468 段(
text/11-ch02-2-getting-started-with-streamlit.txt:466,搜「smoother development」)。 ↩ -
出处:「2 Getting started with Streamlit」第 473–475 段(
text/11-ch02-2-getting-started-with-streamlit.txt:475,搜「Run on Save」)。 ↩ -
出处:「2 Getting started with Streamlit」第 191–194 段(
text/11-ch02-2-getting-started-with-streamlit.txt:193,搜「shut down and restart」)。 ↩ -
出处:「2 Getting started with Streamlit」第 297–303 段(
text/11-ch02-2-getting-started-with-streamlit.txt:298,搜「st to refer to it」)。 ↩ -
出处:「2 Getting started with Streamlit」第 319–324 段(
text/11-ch02-2-getting-started-with-streamlit.txt:321,搜「anonymous inline functions」)。 ↩ -
出处:「2 Getting started with Streamlit」第 328–337 段(
text/11-ch02-2-getting-started-with-streamlit.txt:336,搜「dictionary comprehension」)。 ↩ -
出处:「2 Getting started with Streamlit」第 343–348 段(
text/11-ch02-2-getting-started-with-streamlit.txt:347,搜「toggle to show or hide」)。 ↩ -
出处:「2 Getting started with Streamlit」第 349–355 段(
text/11-ch02-2-getting-started-with-streamlit.txt:354,搜「interesting nuances」)。原文预告:这里有些微妙的细节,第 4 章再深入。 ↩ -
出处:「2 Getting started with Streamlit」第 370–375 段(
text/11-ch02-2-getting-started-with-streamlit.txt:374,搜「semantic styles」)。原文:st.success 和 st.error 是带语义样式的文本容器,大体是绿框和红框。 ↩ -
出处:「2 Getting started with Streamlit」第 376–382 段(
text/11-ch02-2-getting-started-with-streamlit.txt:379,搜「Please enter a password」)。 ↩ -
出处:「2 Getting started with Streamlit」第 384–398 段(
text/11-ch02-2-getting-started-with-streamlit.txt:388,搜「streamlit run <filename>」)。 ↩ -
出处:「2 Getting started with Streamlit」第 419–427 段(
text/11-ch02-2-getting-started-with-streamlit.txt:419,搜「Troubleshooting streamlit run」)。 ↩ -
出处:「2 Getting started with Streamlit」第 429–433 段(
text/11-ch02-2-getting-started-with-streamlit.txt:430,搜「at least one numeral」)。 ↩ -
出处:「2 Getting started with Streamlit」第 454–458 段(
text/11-ch02-2-getting-started-with-streamlit.txt:455,搜「source file has changed」)。 ↩ -
出处:「2 Getting started with Streamlit」第 434–447 段(
text/11-ch02-2-getting-started-with-streamlit.txt:434,搜「Listing 2.2」)。 ↩ -
出处:「2 Getting started with Streamlit」第 483–485 段(
text/11-ch02-2-getting-started-with-streamlit.txt:484,搜「CONNECTING」)。 ↩ -
出处:「2 Getting started with Streamlit」第 486–490 段(
text/11-ch02-2-getting-started-with-streamlit.txt:487,搜「re-establishes the connection」)。 ↩ -
出处:「2 Getting started with Streamlit」第 72–76 段(
text/11-ch02-2-getting-started-with-streamlit.txt:75,搜「incredibly powerful in day-to-day use」)。 ↩ -
出处:「2 Getting started with Streamlit」第 163–170 段(
text/11-ch02-2-getting-started-with-streamlit.txt:35,搜「matter of preference」)。 ↩ -
出处:「2 Getting started with Streamlit」第 18–20 段(
text/11-ch02-2-getting-started-with-streamlit.txt:28,搜「3.11」)。 ↩ -
出处:「Appendix Installing Python and Streamlit」第 9–10 段(
text/22-apx-i-appendix-installing-python-and-streamlit.txt:15,搜「3.10 and above」)。 ↩