惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CERT Recently Published Vulnerability Notes
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
宝玉的分享
宝玉的分享
Microsoft Security Blog
Microsoft Security Blog
Jina AI
Jina AI
L
LangChain Blog
博客园_首页
有赞技术团队
有赞技术团队
The Register - Security
The Register - Security
GbyAI
GbyAI
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
量子位
雷峰网
雷峰网
Security Latest
Security Latest
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
IT之家
IT之家
爱范儿
爱范儿
S
Schneier on Security
N
News | PayPal Newsroom
H
Help Net Security
Recent Announcements
Recent Announcements
Martin Fowler
Martin Fowler
N
News and Events Feed by Topic
C
Cyber Attacks, Cyber Crime and Cyber Security
U
Unit 42
博客园 - 司徒正美
Forbes - Security
Forbes - Security
P
Proofpoint News Feed
W
WeLiveSecurity
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
The Cloudflare Blog
AWS News Blog
AWS News Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
Google DeepMind News
Google DeepMind News
H
Heimdal Security Blog
V
Vulnerabilities – Threatpost
Microsoft Azure Blog
Microsoft Azure Blog
T
Tailwind CSS Blog
G
GRAHAM CLULEY

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观CodeLab Neverland 发布 CodeLab Adapter 3.3.1 DynamicTable 之 纸糊方向盘 CodeLab DynamicTable: 一个可实施的技术方案 CodeLab Insight 发布 Alpha 版 情人节 Home Assistant 周报 && IoT 周报 (02) Joplin: 关注隐私的 Evernote 开源替代软件 浏览器的未来与 Web 传感器 Home Assistant 周报 && IoT 周报 (01) 百宝箱(01) 论自由 介绍 WebThings Home Assistant 周报 && iot 周报 (00) 百宝箱(00) 毛姆读书心得 传世之作 周末徒步 CodeLab Adapter ❤️ Jupyter/Python 航班 躲雨 夏令营途中 [译]思想--作为一种技术 The future of coding 美国之行 三门问题的程序模拟 从Python转向Pharo https://blog.just4fun.site/post/iot/iot-open-source-projects/ Python异步编程笔记 https://blog.just4fun.site/post/iot/iot-open-source-hardware-community/ 万物积木化开发者社区 CodeLab ❤️ Blender Scratch3技术分析之云变量 API(第7篇) [译]对管道(Pipes)的偏爱 [译]提出正确的问题比得到正确答案更重要 蓝牙设备与Scratch3.0 创建你的第一个Scratch3.0 Extension Scratch3技术分析之项目内部数据(第6篇) Scratch3技术分析之社区 API(第5篇) Scratch3技术分析之User API(第4篇) Scratch3技术分析之项目主页API(第3篇) Scratch3技术分析之静态资源API(第2篇) Scratch3.0、micro:bit与Windows7 https://blog.just4fun.site/post/iot/zerynth-vs-micropython/ 核聚变、方所与半宅空间 可视化编程为何是个糟糕的主意 codelab.club周末聚会 关于codelab.club '下一件大事'是一个房间 Hungry Robot - Eat everything 编程作为一种思考方式 今日简史 史蒂夫·乔布斯传 罗素自选文集 https://blog.just4fun.site/post/edx/tianjin-scratch-ai/ https://blog.just4fun.site/post/edx/richie-cms-openedx/ 徒步武功山 WebUSB与micro:bit 积木化编程与3D场景 夜宿武功山顶 scratch3-adapter接入优必选Alpha系列机器人 https://blog.just4fun.site/post/edx/video-migration-note/ scratch3-adapter重构笔记 https://blog.just4fun.site/post/edx/edx-community-members/ 两种硬件编程风格的比较 使用micro:bit自制PPT翻页笔 柏拉图对话集 scratch3.0 + micro:bit 七月电影放映计划 非营利组织的管理 Screenly--用树莓派让任何屏幕变为可编程的数字标牌 以最佳实践开始你的Django项目 micro:bit与事件驱动 为Scratch3.0设计的插件系统(上篇) OCR应用一例 近两年读过的一些好书 blockly开发之使用python驱动浏览器中的turtle(2) 牛顿新传 文学理论入门 逻辑的引擎 人生的意义 blockly开发之生成并运行js代码(1) blockly开发之hello world(0) micro:bit使用笔记 神器之Termux https://blog.just4fun.site/post/iot/micropython-notes/ Cozmo what is this Scratch的前世今生 下段旅程 我行在远方 爆裂 途中杂记 https://blog.just4fun.site/post/edx/open-edx-startup/ cozmo系列之入门 - 有性格且可编程的机器人 PaperWeekly开发笔记 创业二三事
Snap! 中的 Python 解释器
种瓜 · 2024-05-11 · via 夜行人

English version

前言

Snap! 的 JavaScript function 简单, 灵活且强大, 我想模仿它构建 Python function。

我们之前在这篇文章里, 基于 CodeLab Adapter 构建了一个 Python function, 但我一直更想要一个除了浏览器之外没有任何依赖的 Python function。

使用场景

有了 Python function, 我们就可以在 Snap! 中获得:

  • Python 生态中海量的第三方库(opencv-python, numpy…)
  • Python 社区已经实现的各种算法(如 TheAlgorithms)

我们既可以在 Snap! 环境中获得 Python 生态积累的丰富工具, 又可以借助 Snap! 提升 Python 的活性(liveness)。

多个 Python 解释器可运行在浏览器环境。 pyodide 是其中最强大的一个, 它允许我们使用 Python 生态大量的库, 如: opencv-python, Pillow, pyparsing, requests(最新的版本有问题), retrying, scikit-image 以及大量的科学计算相关的库(scipy, sympy, numpy, pandas)

实际上, pyodide 支持 任何纯 Python 实现的库(构建为 wheel), 使用了 C/C++ 代码的库(如 numpy)编译为 WebAssembly 也能够在 pyodide 中使用。

我们打算基于 pyodide 构建 Python function。

将 pyodide 引入 Snap!

目标

与我们上篇文章引入 mediapipe 库一样, 我们希望实现以下 2 个目标:

  1. 无需更新平台, 不需要开发者介入, 所有工作都在用户环境中完成(只是一个 Snap! 项目), 这意味着普通用户可以继续延伸这些能力。 (这是终端用户编程的一个例子)
  1. 可以充分利用 Snap! 的活性(liveness), 享受高效而愉快的开发体验。

由于一切都只是一个 Snap! 项目, 你可以随意调整它, 甚至使用其他的 Python 解释器替代 pyodide。

导入 pyodide

与 mediapipe 不同, pyodide 不是以模块的形式发布, 而是采用了更传统的全局引入。 我们可以使用 src_load(url) 引入它。

我们使用的 pyodide 版本为 0.25.1, 它所对应的 Python 版本为 3.11

我们没有采用官方的 CDN, 而是将 pyodide 部署到了国内的 CDN 上。

demo

使用 requests 与网络交互

Snap! 有一个积木用于与网络交互, 但使用起来不是很便利, requests 的 API 设计得非常简单易用:

requests demo

解析 XML

Snap! 没有内置 XML 库, Python 内置的 XML 库很好用,我们可以使用它从博客 rss 中提取信息。

这个例子展示了从博客获取最新 rss, 使用 python 的 xml 库解析它, 并将解析结果存入 posts 变量。之后将每篇博文显示为一个克隆体:

  • 克隆体的外观是文章标题
  • 鼠标在克隆体上悬停时,展示文章摘要
  • 点击克隆体将打开文章链接

XML demo

正则表达式

Snap! 缺少正则表达式相关的支持, 我们可以使用 python 的正则表达式模块增强它

在 Python 与 Snap! 之间传递列表

这个例子展示了如何在 Python 与 Snap! 之间传递列表(任意嵌套深度!)

列表几乎可以承载一切的数据结构.Python 和 Snap! 的列表功能都极其强大(Snap! 由于是 lisp, 列表处理能力比 python 更强大),现在这二者可以无缝互操作了。

图像、音频等多媒体数据全都可以表示为列表/矩阵,所有这些数据都能够在两个系统中随意流动了

一个典型的用例是, numpy 的所有能力都可以进入 Snap! 中, 反过来 Snap! 又可以为 numpy 提供 liveness 的增强

传递列表 demo

在 Python 与 Snap! 之间传递 json

对于复杂的数据结构, 可以考虑使用 json 传递. 也可以使用 json 来传递列表 (将列表作为一个 key 的 value ).

传递 json demo

numpy demo

numpy demo

OpenCV demo

OpenCV demo

Pillow demo

Pillow demo

社区第三方库

前边说到:

pyodide 支持 任何纯 Python 实现的库(构建为 wheel)

我们试着安装 furl 库, furl 用于方便地处理 url

pyodide 将从 pypi 上安装这个库(你也可以从指定的 url 安装自定义库)。

furl demo

FAQ

如何保存状态

函数通常是无状态的, Python function 是一个函数。

如果你期望在多个函数调用中, 操作同一个状态变量, 可以把它存放在 window 全局变量里:

1
2
3
import js
js.window._result = "hello"
# 可在 devtool 中访问: console.log(window.a)

当然你也可以把它持久化存储在 localstorage 或 indexeddb, 这样即使刷新浏览器, 也还能找到这些状态。

如何调用蓝牙, 串口等浏览器 API

这个 demo(点击体验) 展示了如何使用 Python 连接 MicroBlocks 的蓝牙服务。

第三方库从哪儿加载?

load package 积木用于从网络加载第三方库, 它在背后使用了 micropip

可以从多种来源加载 python 包:

  • pyodide 官方默认编译了这些 Python 库, 如果你加载这些库, 将默认从 pyodide 仓库里加载(我已经把它们放在了国内 CDN 上), 所以加载速度应该很快
  • 其他的库默认从 pypi 安装

你也可以直接从 url 中加载库(你可以把它们托管在自己的服务器上), 如: https://wwj718.github.io/post/img/furl-2.1.3-py2.py3-none-any.whl

如何在 Snap! 和 Python 之间传递图像文件?

跨语言/系统传递媒体类信息(音频、图片)的常见做法是使用 base64 格式, 本文的例子采用的也是这种做法。

这个对话 中, ChatGPT 解释了这些这个格式编码的 png 格式。

你可以直接将 base64 编码的字符串(形如: data:image/png;base64,iVBORxxxx...)粘贴到 Chrome 浏览器的输入栏中浏览图片:

如何将积木编译为 Python 代码?

通常而言,这不是个好想法, Snap! 的 lisp code 要更为强大(因为它与积木是同构的)。 如果确实需要编译为 Python,可以参考这个项目

如何使用更专业的 Python 编辑器?

在 Snap! 积木中写 Python 代码无法使用自动补全等功能, 如何使用更专业的 Python 编辑器?

一个思路是使用 iframe 库 引入 pyscrit(pyscrit-editor) 或者 marimo 这样更专业的 Python 编辑器, 然后使用 dynatalk-over-postmessage 进行消息传递

如何将其转化为标准的 Snap! 库?

目前 Python function 已成为了 Snap! 中文版 内置库.

更多细节参考 如何将其转化为标准的 Snap! 库?

结论

本文构建了与 JavaScript function 风格相同的 Python function 积木,一切都运行在浏览器中,没有任何外部依赖。 所有工作都在积木环境中完成,没有修改一行 Snap! 源代码。

最令人满意的是所有这些扩展性都掌握在普通用户自己的手里,无需开发人员的介入,也无需更新平台。一切都只是一个普通的 Snap! 项目!

参考