6

Snap! 使用笔记: Python function

 1 year ago
source link: http://wwj718.github.io/post/%E7%BC%96%E7%A8%8B/snap-python-function/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

制造伟大的、可成长的系统的关键是设计出模块之间的沟通机制,而不是关于内部属性和行为应该是什么。 – Alan Kay

Snap!JavaScript function 设计得极为出色, 仅通过一个积木就将浏览器的所有能力带给了 Snap! 。 它给了我巨大冲击。 关于这点我们在 Snap! 使用笔记: JavaScript function 做了讨论。

为了将 Snap! 用作日常计算/编程环境,需要突破浏览器的限制,使其得到操作系统的所有能力。我打算沿着Jens Mönig(Snap! 创始人)的设计思路, 来做这件事。

先前的工作

之前我基于 CodeLab Adapter 的消息系统为 Snap! 接入 Python 来达成这个目标。想法是: 如果我们能够完成 Snap! 与 Python 的互操作,就能在 Snap! 中完成任何工作, 因为 Python 解释器封装了底层操作系统的所有接口(Python 通常被认为是更好的 Bash), 如此一来我们就可以在 Snap! 里进行 系统 io 编程、管理远程服务器、渗透测试、与其他进程互操作…

以下是一些我渴望在 Snap! 中获得的系统能力:

  • 处理文件/文件夹/路径
    • Python 库: pathlib
    • 以 GUI 的方式打开文件/软件/目录: from codelab_adapter.utils import open_path_in_system_file_manager
  • 调用命令行工具
    • Python 库: subprocess、sh
  • 与网络交互
  • 接管鼠标键盘

由于接入了 Python, 我们不仅得到了与浏览器之外的系统交互的能力, 还得到了 Python 的巨大生态库:

  • 计算机视觉
    • OpenCV
  • 神经网络
    • PyTorch、TensorFlow
  • 各类机器人驱动库…

最初我们在 CodeLab Scratch 里实现了这些想法, 它体现为 Python 插件:

Snap-Python-function-02.png

我最近将其移植到了 Snap! 中:

Snap-Python-function-01.png

所以它的使用方式和最初的文档记录的使用方式,完全一致:

先前的插件存在一个问题: 不够 lively。 它类似于Snap! 使用笔记: JavaScript function里提到的使用 primitive 扩展 Snap! : 需要先在 Jupyterlab 中编写 Python 代码, 然后重启 extension_python 插件, 之后在 Snap! 里调用它, 虽然无需刷新 Snap! 页面,但切换到 Jupyterlab、重启插件, 依然打断我的思路。

由于受到 JavaScript function 的强烈冲击, 我打算以类似的方式来做这件事: 将操作系统的所有能力带给 Snap! (通过与 Python 互操作)。

Python function 插件

这些想法的最终产物是 Python function 插件:

Snap-Python-function-03.png

Python function 并没有设计成单个积木, 而是设计成了一个插件, 里边多了一些辅助类积木。

为了使用 Python function 积木, 你需要做 3 件事(与JavaScript function一致):

  1. 打开权限
    1.1. 开启 CodeLab Adapater
    1.2. 开启 extension_python 插件
    1.3. 设置 token(出于安全考虑)
  2. 编写 Python 函数
  3. 调用 Python 函数

1. 打开权限

  • 1.1. 开启 CodeLab Adapater

下载最新的 CodeLab Adapater, 并运行它。

CodeLab Adapater 正常运行之后,你会在 CodeLab Snap! 页面里看到这个绿色的圆点(和 CodeLab Scratch 类似)

Snap-Python-function-04.png

如果 CodeLab Adapater 没有启动或出了问题,这个原点就会是灰色的。

  • 1.2. 开启 extension_python 插件

Snap-Python-function-05.png
  • 1.3. 设置 token (出于安全考虑)

Snap-Python-function-07.png

2. 编写 Python 函数

Snap-Python-function-06.png

Python function 插件中找到 Python function 积木。上图编写了一个匿名函数, 参数是 path, 函数体是打开它(可能是目录、文件或系统里的 GUI 软件)。

附上相应 Python 代码

from codelab_adapter.utils import open_path_in_system_file_manager
open_path_in_system_file_manager(path)

3. 调用 Python 函数

接下来我们就可以调用它。

Snap-Python-function-08.png

JavaScript function 一样, 有两个积木可用于执行 JavaScript function:

  • 运行(没有返回值)
  • 调用(有返回值)

这两个积木都内置在 Python function 插件里(底层实现与控制组里的同名积木并不相同)

更复杂的例子, 可以右键查看examples积木的定义:

Snap-Python-function-09.png

Snap! 使用笔记: JavaScript function 提到的用例类似。

我不仅使用 Python function 来增强 Snap!, 也借助 Snap! 的个人计算环境来探索 Python 以及背后的操作系统。

此外有一个有趣的用例是, 使用 Python function 来执行 Codification 示例自动生成的 Python 代码:

Snap-Python-function-15.png

安装第三方库

我喜欢使用 sh 库来在 Python 里使用 linux 工具箱。

CodeLab Adapter 没有内置这会库, 但你可以自行安装它:

Snap-Python-function-10.png

安装完成之后,就可以使用它了:

Snap-Python-function-11.png

按行分割,将它们转化为列表:

Snap-Python-function-12.png

由于 Snap! 从 Lisp 那里继承了处理列表的强大能力, 又从 Smalltalk 那里继承了 liveness 的特质, 现在你就可以以 lively 方式随意摆弄它们了!

从 Snap! 中调用 Python 函数时, Snap! 的数据类型会自动转化为 Python 类型, 随意你可以随意使用内置积木调用 Python 函数。

从 Python 中返回的简单数据类型(字符串、数字), 会自动转化为 Snap! 数据类型. 当你想将复杂数据结构 return 到 Snap! 里时,建议使用 json 序列化你的数据(examples积木里有例子), 然后在 Snap 中处理 json 即可。

这些匿名函数转瞬即逝,有时,你希望让计算的结果贮存在全局空间,可以在不同函数里读写它

Snap-Python-function-14.png

这使得许多事情变得简单

extension_python 以线程的方式启动, 有一些库需要在独立进程里启动(非常罕见)。如果你遇到这类问题,可以发邮件跟我讨论。

由于 extension_python 是开源的,你可以自行修补它,使用一些 hack 技巧,总是可以绕过限制。

我目前还没有遇到过这些限制。

尽可能少地引入 primitive 是 Smalltalk 社区编写 primitive 遵循的风格, 关于 primitive 的 big ideas, 我在 MicroBlocks 与 Snap!的互操作里(视频)提到过一些 – Snap! 使用笔记: JavaScript function

当我在 Snap! 中使用 Python 时,我也遵循类似的风格, 尽可能少地引入底层的能力(除非必要), 尽可能多地使用 Snap! 积木来编程。

我希望涉及 Python 的部分足够小, 一般而言是为了补充浏览器没有的能力(本地系统功能、网络),我将多数的计算过程放在 Snap! 里,借助 Snap! 这样的个人计算环境,我可以直观触摸到数据,以及充分利用个人计算环境的其他杠杆力量。

Python function 的 Python 代码,最终运行在 CodeLab Adapater 内置的 Python 解释器里。未来我们也可能支持基于 WebAssembly 的 Python 解释器(如Pyodide)。

递归是我之前最恐惧的领域之一,但在 Snap! 里玩耍它几乎是一种消遣。 因为你可以"看见"并把玩程序与数据结构。

Snap-Python-function-13.png

这一段代码,使用递归将 Snap! 数据类型递归转化为 Python 数据类型, 它可以处理任意深度的 Snap! 列表。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK