Reflex 是最适合全栈 Web 开发的 Python 框架吗?

BBetter Stack
Computing/SoftwareSmall Business/StartupsInternet Technology

Transcript

00:00:00你是 Python 的死忠粉吗?我是指那种只想写 Python 代码,
00:00:05不想碰其他任何东西的人?如果你是这类开发者,那么我有个非常适合你的东西。
00:00:11它是一个叫作 Reflex 的框架,旨在解决将全栈 Python 代码
00:00:17转化为生产级 Web 应用时所面临的摩擦和复杂性。在今天的视频中,我们将探讨
00:00:22Reflex 是什么、它是如何运作的,并看看它为什么这么火。
00:00:30Reflex 想要解决的核心问题是,Python 开发者为了能给自己的代码
00:00:36构建一个功能齐全的 Web 界面,往往被迫去学习一套完全不同的技术栈,包括 JavaScript、React、路由和打包工具。
00:00:43Reflex 让开发者能够使用 100% 纯 Python 构建全栈应用,
00:00:50因此你可以专注于使用一种语言完成整个技术栈,无需频繁切换思维背景。
00:00:56官方声称,自发布以来,开发者已经使用该框架构建了超过 100 万个应用,
00:01:03而且 30% 的财富 500 强公司正将其用于内部工具开发。
00:01:10最近,他们大举进军 AI 领域,推出了一款名为 Reflex Build 的工具,
00:01:15基本上让你通过单条提示词就能“凭感觉”写出你的应用。
00:01:21此外,他们还支持其他 SDK 和工具的集成,让你能轻松地将应用
00:01:26连接到 Databricks、Okta、Stripe、AWS 等流行服务。虽然听起来很厉害,
00:01:34但我还是想亲自动手试试这些代码,看看它究竟是如何运作的。
00:01:40我们先创建一个新目录 ReflexTest,然后进入该目录。从这里开始,
00:01:44文档说我们可以运行这三个命令来启动我们的 Reflex 项目。首先
00:01:48运行 `pip install reflex`,然后执行 `reflex init`。这里会询问我们
00:01:53是否使用官方模板。但为了演示,我们保持简单,选择“blank reflex app”选项。
00:01:57完成后,我们可以在代码编辑器中打开项目。进入 reflex_test 文件夹,
00:02:02我们整个应用的代码都写在 `reflex_test.py` 文件里。可以看到,
00:02:09它包含一个 RX 组件部分和一个 State 类。在终端运行 `reflex run`(此处修正为运行命令)来启动应用。
00:02:15它会在 3000 端口启动应用,我们可以在浏览器中看到结果。
00:02:20现在来看看 Reflex 如何管理状态。我们先添加一个简单的 count 变量。
00:02:25为了改变这个值,我们需要定义一个函数来实现。在 count 变量下方,
00:02:29我们可以定义一个 increment 函数,让 count 加 1。官方推荐
00:02:34在函数上方添加 `@rx.event` 装饰器,这有助于静态类型检查,
00:02:39并确保事件处理器接收到正确数量和类型的参数。接着,我们可以在
00:02:44RX 组件的 return 语句中添加一个简单的按钮。它会在文本框中显示计数值,
00:02:48并在点击时触发 increment 函数。Reflex 支持热重载,所以如果我们
00:02:53现在保存文件并打开浏览器,就能看到计数按钮,每次按下都会增加数值。
00:02:58现在试点更有趣的。我们在 state 中创建一个项目数组。
00:03:02理论上,我们应该能通过这样的内联 for 循环将这些项目渲染成列表。
00:03:08但这样行不通,因为这个值在编译时是未知的。你看,
00:03:13Reflex 的运作方式是:当你运行应用时,前端会被编译成在浏览器中运行的 JavaScript 代码,
00:03:18这在 Reflex 术语中被称为“编译时”。而后端保持 Python 运行,
00:03:23在应用生命周期内运行在服务器上。这在 Reflex 术语中被称为“运行时”。
00:03:27所以我们不能在组件渲染块中使用纯 Python 的 for 循环,但可以
00:03:32在渲染块之外进行纯 Python 操作。那么如何在组件块中循环遍历项目呢?
00:03:37在这种情况下,我们需要定义一个简单的 `render_item` 函数来渲染项目,就像这样。
00:03:42然后在组件渲染块中使用 `rx.foreach` 函数来执行循环。
00:03:47现在我们可以看到项目在应用中正常渲染了。条件渲染也是同样的道理。
00:03:53我们不能在 return 块中直接写 if-else 语句,就像这样。相反,
00:03:58我们需要使用 `rx.cond` 函数。如果我们现在点击按钮超过 5 次,
00:04:02应用上就会弹出相应的文本。最后要看的是我们如何获取并渲染数据。
00:04:08为了演示,我们从“随机冷知识 API”中获取一个冷知识并显示在文本框中。
00:04:12首先,添加一个布尔变量来表示是否正在获取数据,以及一个用于存放知识的空字符串。
00:04:17然后定义一个异步的数据获取函数,先将 data_fetching 设为 true。
00:04:22接着使用 HTTPX 库来获取随机冷知识,并将其存储在我们的 fact 状态变量中。
00:04:27我还用 asyncio 添加了一秒钟的延迟,这样我们就能实时看到数据获取的过程。
00:04:33操作完成后,我们将 data_fetching 布尔值设回 false。注意这里我们
00:04:38使用了 yield 操作。每当我们需要在一个事件处理器中多次更新 UI 时,
00:04:43可以使用 yield 来向渲染器发送更新。在这个例子中,一旦 data_fetching 发生变化,
00:04:48我们就希望 UI 能立即反映出这一变化。别忘了在顶部
00:04:52添加 HTTPX 和 asyncio 的导入。最后,在我们的渲染函数中,
00:04:57可以使用一个简单的 `rx.cond` 函数,根据当前状态显示加载动画或冷知识内容。
00:05:03如果我们希望每次加载页面时都触发这个函数,需要给 RX 组件添加一个装饰器,
00:05:08让它在页面加载时触发我们的 `fetch_data` 函数。现在刷新页面,
00:05:12就可以看到随机冷知识被获取并渲染到了页面上。最后我想带大家
00:05:18看看 `.web` 文件夹。正如你所见,我们刚才写的所有代码底层都被编译
00:05:22并渲染成了一个 React 应用,它在底层使用了 Vite 和 Tailwind。
00:05:27它甚至还有用于路由处理的 React Router。说实话,一看到这个,
00:05:33我感到非常失望。我原以为他们构建了一个自定义的 JavaScript 编译器或者什么原创的东西。
00:05:38但这仅仅意味着 Reflex 只是 React 之上的又一个抽象层。所以我对 Reflex 的感觉
00:05:42比较复杂。一方面,拥有一个让你能用纯 Python 编写一切的全栈框架的想法确实很酷。
00:05:47但当我发现它的底层只是包装了一个 React 应用,而不是使用原生 Python 时,我非常失望。
00:05:53这反而让事情变得更复杂了,因为你现在被迫去学习一套新的架构并理解
00:05:59Reflex 是如何处理状态管理的,更不用说可能出现的各种边缘情况了,你还不如直接用 React,
00:06:05毕竟它是一个经过实战检验且成熟稳固的框架。所以,如果我要创建一个
00:06:11使用 Python 后端的项目,我前端依然会选择使用 JavaScript 框架。
00:06:16Reflex 并没有说服我全面转向全栈 Python 开发。但这只是我的个人拙见。
00:06:22你对 Reflex 有什么看法?你喜欢这种全栈 Python 框架的构思吗?
00:06:28我真的很想知道大家是怎么想的。伙计们,如果你喜欢这个视频,
00:06:34一定要给视频下方的点赞按钮来上一拳。别忘了订阅我们的频道。
00:06:39我是来自 Better Stack 的 Andris,我们下个视频再见。
00:06:44us know by smashing that like button underneath the video. And don't forget to subscribe to our channel.
00:06:50This has been Andris from better stack and I will see you in the next videos.

Key Takeaway

虽然 Reflex 提供了纯 Python 开发全栈应用的便利性,但由于其底层本质是 React 的抽象层,开发者仍需面对复杂的编译机制和特定的状态管理架构。

Highlights

Reflex 是一个旨在让开发者仅使用 Python 即可构建全栈 Web 应用的框架,无需掌握 JavaScript 或 React。

该框架已在财富 500 强公司中得到应用,并推出了基于 AI 的快速原型开发工具 Reflex Build。

Reflex 区分了“编译时”(前端 React 编译)和“运行时”(后端 Python 执行)的概念。

在处理循环(rx.foreach)和条件判断(rx.cond)时,Reflex 有其特定的语法约束,无法直接使用纯 Python 逻辑。

状态管理通过 State 类实现,并利用 @rx.event 装饰器和 yield 关键字进行异步 UI 更新。

视频作者对 Reflex 仅作为 React 之上的抽象层表示失望,认为这增加了架构的复杂性。

Timeline

Reflex 框架简介与市场地位

视频开篇介绍了 Reflex 这一专注于 Python 开发者的全栈框架,旨在消除学习 JavaScript、React 等前端技术栈的摩擦。主讲人指出,Reflex 允许开发者在单一语言环境下完成从路由到打包的全部工作,有效避免了思维背景的频繁切换。据统计,已有超过 100 万个应用使用该框架构建,且 30% 的财富 500 强公司将其用于内部工具。此外,Reflex 还积极拥抱 AI 趋势,推出了 Reflex Build 工具并支持与 AWS、Stripe 等主流服务集成。这一部分强调了 Reflex 在提升开发效率和降低入门门槛方面的潜力。

项目初始化与基础架构

在这一部分,主讲人演示了如何从零开始搭建一个 Reflex 项目,包括安装 `reflex` 库和执行初始化命令。通过 `reflex init` 命令,开发者可以选择不同的模板,本例中选择了最基础的空白应用模板。项目结构相对简单,核心逻辑集中在 `reflex_test.py` 文件中,主要由 UI 组件部分和 State 类组成。启动应用后,Reflex 默认在 3000 端口运行,提供即时预览功能。这展示了 Reflex “开箱即用”的特性,让 Python 开发者能迅速建立起 Web 开发环境。

状态管理与事件处理机制

主讲人详细讲解了 Reflex 如何处理状态更新,以一个简单的计数器应用为例进行说明。开发者需要在 State 类中定义变量,并通过装饰有 `@rx.event` 的函数来修改这些变量。这种装饰器不仅有助于静态类型检查,还能确保事件处理器接收到正确的参数。UI 端的按钮通过点击事件触发这些后端函数,实现数据的交互。得益于框架支持的热重载功能,开发者在保存文件后可以立即在浏览器中看到状态更新的结果。这一节突出了 Reflex 将后端逻辑与前端 UI 绑定的直观方式。

编译时与运行时的核心限制

这一章节深入探讨了 Reflex 的底层逻辑,解释了为什么开发者不能在组件块中直接使用 Python 的 for 循环或 if 语句。主讲人提出了“编译时”与“运行时”的区别:前端会被编译成浏览器运行的 JavaScript,而 Python 代码则运行在服务器端。因此,循环必须使用 `rx.foreach`,而条件渲染则需依赖 `rx.cond` 函数。这种限制是因为编译后的代码需要能够动态响应浏览器中的状态变化。通过演示 `render_item` 函数和点击 5 次以上的条件触发,主讲人展示了如何适配 Reflex 的特定语法。这揭示了在使用该框架时,开发者仍需理解其特有的架构规则。

异步数据获取与实时 UI 更新

主讲人演示了如何从外部 API 获取随机冷知识,并展示了复杂的异步操作流程。通过引入 HTTPX 和 asyncio 库,程序在获取数据时会设置加载状态,并使用 `yield` 关键字向 UI 发送多次状态更新。这种机制允许用户在等待数据返回时看到“加载中”的动画,极大地提升了用户体验。为了让应用在页面加载时自动运行函数,主讲人还使用了专门的装饰器。最后,通过实际的页面刷新演示,验证了从发起请求到渲染内容的完整闭环。这一部分展示了 Reflex 处理真实业务场景中异步任务的能力。

底层原理剖析与最终总结评价

在视频的最后阶段,主讲人检查了项目底层的 `.web` 文件夹,发现 Reflex 实际上是被编译成了基于 Vite 和 Tailwind 的 React 应用。这一发现让他感到非常失望,因为他原本期待看到一种更具原创性的原生 Python 编译器。他认为,Reflex 只是在 React 之上增加了一个抽象层,这可能会引入更多边缘情况和维护复杂性。主讲人总结道,与其学习这种复杂的包装层,不如直接学习成熟的 React 框架。尽管 Reflex 的出发点很好,但他目前仍倾向于使用 JavaScript 框架处理前端,而将 Python 留在后端。最后他邀请观众分享对这种全栈 Python 框架的看法,并结束了视频。

Community Posts

View all posts