目录
平时我们在网上看到的一个个精美的网页、流畅的交互,都是由前端开发工程师们开发出来的。要想开发出这些前端页面内容,需要了解Html、JS、CSS等代码知识以及一定的审美能力,对于像我这种只能熟练使用Python语言的“外行”来说无疑有着巨大的学习成本,那么有没有快速实现一个前端页面的方法呢?答案就是本文要介绍的两个Python框架:PyWebIO、Streamlit。
框架简介
先看看两个框架的官方介绍:
PyWebIO provides a diverse set of imperative functions to obtain user input and output content on the browser, turning the browser into a "rich text terminal", and can be used to build simple web applications or browser-based GUI applications. Using PyWebIO, developers can write applications just like writing terminal scripts (interaction based on input and print function), without the need to have knowledge of HTML and JS. PyWebIO is ideal for quickly building interactive applications that don't require a complicated user interface.
Streamlit is an open-source Python library that makes it easy to create and share beautiful, custom web apps for machine learning and data science.
通过上面的两段介绍👆🏻,我们可以知道这两个框架均可以使用纯Python来进行编写而无需了解前端代码语言,不同的是PyWebIO直接说明是为了快速构建Web应用,而Streamlit则是为了机器学习和数据科学,目标点不同。不过这对于我们一般使用是没影响的,下面来看一下我简单总结的这两个框架的基本使用吧!
使用方法
1. PyWebIO的使用
安装方法
PyWebIO作为Python的一个第三方包,那么就可以直接使用pip3 install pywebio
来进行安装,安装成功后就可以正常使用了。
pdm add pywebio
Adding packages to default dependencies: pywebio
✔ 🔒 Lock successful
Changes are written to pdm.lock.
Changes are written to pyproject.toml.
Synchronizing working set with lock file: 4 to add, 0 to update, 0 to remove
✔ Install pywebio 1.6.3 successful
✔ Install tornado 6.1 successful
✔ Install ua-parser 0.16.1 successful
✔ Install user-agents 2.2.0 successful
🎉 All complete!
注:我使用的是PDM来管理依赖包,所以使用的命令是pdm add pywebio
,效果是一样的。
第一个例子
安装好之后,就可以直接使用了,pywebio主要分为输入模块、输出模块两个大的部分,我们就分别使用这两个模块里的方法来实现一个输入出生年月来计算年龄的简单功能。
from pywebio.input import input, NUMBER
from pywebio.output import toast, popup, PopupSize
import arrow
def get_age(birth: int) -> int:
"""计算年龄"""
now_time = arrow.now()
return now_time.year - birth
# 输入出生年
input_birth = input(label="出生日期", type=NUMBER, placeholder="请输入出生年份", required=True)
# toast显示计算结果,并且点击后弹窗
toast(
content=f"您的年龄是:{get_age(input_birth)} 岁",
position="center",
duration=5,
color="success",
onclick=lambda: popup("被点了", "阿巴阿巴阿巴", size=PopupSize.LARGE),
)
运行代码会自动使用默认浏览器打开一个页面,显示内容如下:
输入一个年份,比如1990,点击提交按钮
继续点击改消息
代码解释
上面我们用了一个简单的例子来进行了一个演示,接下来我们就逐行分析一下代码,看看每个代码都是什么意思!
- 导入部分:
可以看到我们一个使用了三行导入内容,其中第一行是导入了pywebio的input模块下面的input方法和NUMBER(一个常量),第二行是导入了output模块下的toast、popup方法和PopupSize类。input和output两个模块是pywebio的两个核心模块,包含了所有前端组件,分别有以下方法:
函数 | 简介 |
文本输入 | |
多行文本输入 | |
下拉选择框 | |
勾选选项 | |
单选选项 | |
滑块输入 | |
按钮选项 | |
文件上传 | |
输入组 | |
更新输入项 |
函数 | 简介 | |
输出域Scope | 创建一个新的scope. | |
进入输出域 | ||
获取当前正在使用的输出域 | ||
清空scope内容 | ||
移除Scope | ||
将页面滚动到 scope Scope处 | ||
内容输出 | 输出文本 | |
输出Markdown | ||
put_info*† | 输出通知消息 | |
输出Html | ||
输出链接 | ||
输出进度条 | ||
输出加载提示 | ||
输出代码块 | ||
输出表格 | ||
输出按钮,并绑定点击事件 | ||
输出图片 | ||
显示一个文件下载链接 | ||
输出横向标签栏Tabs | ||
输出可折叠的内容 | ||
固定高度内容输出区域 | ||
输出自定义的控件 | ||
其他交互 | 显示一条通知消息 | |
popup*† | 显示弹窗 | |
关闭正在显示的弹窗 | ||
布局与样式 | put_row*† | 使用行布局输出内容 |
使用列布局输出内容 | ||
使用网格布局输出内容 | ||
在 put_table() 和 put_grid() 中设置内容跨单元格 | ||
自定义输出内容的css样式 |
我们这里用到了输入模块中的input、输出模块的toast、popup
而第三行arrow是一个处理日期的第三方包,个人觉得很好用,比Python自带的更简洁易用,推荐👏🏻
- get_age(birth)方法
该方法的作用是根据输入的日期来计算年龄,比较简单。注意,这里的仅做演示,如果是实际的工作中需要考虑各种情况,比如不能大于当前年份等。
- input部分
这一行的作用就是在页面中绘制一个输入框,各个参数的含义:
-
- label:输入框标签,也就是页面输入框上方显示的文字;
- type:输入框允许输入的类型,这里因为需要用到的是年份并在get_age()方法中参与减法运算,所以使用了NUMBER类型,即数字。其他还有
TEXT
,NUMBER
,FLOAT
,PASSWORD
,URL
,DATE
,TIME
,COLOR
,DATETIME_LOCAL
等,按需导入即可; - placeholder:输入框的背景提示内容
- required:当前输入是否为必填项,默认为
False
其他还有很多参数,详情可以查阅官方文档
- toast部分
toast的方法是在点击了input的提交按钮后,弹出一个提示信息,各个参数的含义:
-
- content:通知显示的内容,这里调用了get_age()方法,入参是input输入框中输入的年份。这里也可以使用匿名函数:
- position:通知显示的位置为
center
,即居中显示,其他的还有left
、right
- duration:通知显示持续的时间,单位为秒。 0 表示不自动关闭(此时消息旁会显示一个关闭图标,用户可以手动关闭消息)
- color:通知消息的背景颜色,可以为info、error、warn、success或以 '#' 开始的十六进制颜色值
- onclick:点击通知消息时的回调函数,回调函数不接受任何参数。例子中的代码使用了lambda的匿名函数,调用了output模块中的popup方法(显示弹窗)
2. Streamlit的使用
安装
使用命令pip install streamlit
来进行安装,安装完成后,在命令行中输入streamlit hello
来进行验证,如果可以打开一个网页则说明安装成功。注:streamlit支持Python版本需要 > 3.7。
接下来,我们使用streamlit来实现和上面一个例子相同的功能
import streamlit as st # 生成网页
import arrow
st.title("生日计算")
birth = st.text_input(label="请输入出生日期")
if st.button(label="开始计算"):
st.success(f"您的年龄是:{arrow.now().year - int(birth)} 岁")
在命令行中输入:streamlit run streamlit_demo.py
,其中streamlit_demo.py为上述代码保存的文件名称,运行成功后命令行会显示以下内容并且在浏览器中自动打开一个网页(如果没有自动打开,可以手动输入命令行中显示的URL)
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501
Network URL: http://172.16.152.150:8501
For better performance, install the Watchdog module:
$ xcode-select --install
$ pip install watchdog
输入一个年份后,点击计算
代码解释
- 第一二行为导入依赖包
- st.title()方法:在页面中显示一个加粗的标题
- st.text_input()方法:创建一个文本输入框,同样,这里仅做演示,并没有过多的去考虑不同情况。
- st.button()方法:创建一个按钮,当点击时(True)调用
st.success()
方法 - st.success()方法:显示一条成功类型的消息(绿色),同样的还有
error()
、warning()
、info()
方法
综合对比
- 通过我一段时间的使用下来,个人觉得Streamlit的组件类型要更丰富,通过多App组合的形式甚至可以开发出一个完整的后台应用。同时对Pandas数据的支持很友好,可以直接输出各种类型的图表,而PyWebIO则是要通过第三方的库来完成数据可视化功能,如Bokeh、pyecharts、plotly等;
- Streamlit支持使用缓存来提高页面访问性能。
- Streamlit有一个特色功能:Streamlit Cloud,即通过注册账号后,将自己写的代码快速部署到公共服务器上来供人访问,简单快捷。但这点对我来说恰恰是一个缺点,因为一些代码本身具有私密性,我并不想部署到公共的服务器上而是希望它可以进行私有化部署,这是Streamlit不支持的。而PyWebIO对这点的支持却很好,即可以简单的使用
start_server()
来快速的启动一个服务,同时也对Python主流的Web框架基本都可以支持,包括Tornado、Flask、Django、aioHttp、FastAPI等,几行代码便可以集成挂载到这些框架中。 - 另外,PyWebIO的会话默认是基于线程的,同时还提供了基于协程的会话,对于IO密集型的任务,协程比线程占用更少的资源同时又拥有媲美于线程的性能。 另外,协程的上下文切换具有可预测性,能够减少程序同步与加锁的需要,可以有效避免大多数临界区问题。
综上所述,两款工具无论哪一个均可以让一个不懂前端代码知识的人快速的写出一个Web页面,而如果需要私有部署,那么PyWebIO可以很好的满足你的要求;如果是想要快速的进行数据可视化,那么Streamlit则更适合,毕竟本身就是为了 machine learning and data science来开发的。所以,两款工具都可以学习一下,然后根据自己的实际需要来决定吧!