Skip to content

Python 程序 ​

除了用节点画布编写的图形程序(Graph),程序还可以直接调用 Python 脚本(Python)。把程序类型设为 Python、指定脚本文件与入口函数后,程序运行时就会调用该函数,从而在图形程序中复用已有的 Python 代码。

INFO

Python 程序在运行时被当作自包含的单个 .py 文件加载,因此存在一些限制,详见脚本的执行方式。

用途 ​

  • 实现复杂的计算与逻辑:在画布中完成复杂计算往往需要连接大量节点,把这些计算交给 Python 可以避开繁琐的连线,也便于复用已有的 Python 代码与第三方库;
  • 扩展软件功能:Python 程序可以像内置节点一样被图形程序调用(见在图形程序中调用 Python 程序),因此可以用它实现基于 Python 的自定义节点,补充内置节点没有的能力。

新建 Python 程序 ​

  1. 点击程序列表面板的 + 按钮,打开“新建程序”对话框。
  2. 在“类型”中选择 Python,填写名称与描述后点击“确认”。
  3. 在 Python 面板中填写:
    • 函数名:脚本中被调用的函数名(不含括号),例如 run;
    • 脚本路径:.py 文件的位置。点击搜索按钮可以浏览选择,也可以把 .py 文件直接拖到面板上。
  4. 在选项面板中添加输入选项和输出选项,它们决定函数接收的参数与返回的值,详见调用约定。

函数名右侧是运行(F5)按钮,脚本路径右侧是选择、编辑、刷新和定位按钮;脚本内容以只读方式显示在面板下方,点击“刷新”可重新载入脚本内容,点击“编辑”会使用系统默认的编辑器打开脚本。

如果脚本位于程序的目录中,则会以程序相对路径保存,程序导出/导入时会一并迁移。

调用约定 ​

参数 ​

函数按输入选项的先后顺序接收位置参数:

选项类型传入的 Python 值
整数int
浮点数float
布尔bool
字符串str

其余类型(JSON、向量、图像等)目前不能作为 Python 程序的输入。

返回值 ​

函数返回的值按输出选项的先后顺序写入输出选项:

函数的返回对应关系
None(或不返回值)程序不能有输出选项
单个值程序只能有一个输出选项
元组按顺序对应各个输出选项

返回值的个数必须与输出选项的个数一致,否则运行时会报错。返回值同样只支持 int、float、bool、str 四种类型。

示例 ​

程序有一个输入选项(整数 秒)和两个输出选项(字符串 文本、整数 长度):

python
def run(seconds):
    text = f"waited {seconds}s"
    return text, len(text)

函数也可以是 async def,此时会等待协程执行完毕:

python
import asyncio

async def run(seconds):
    await asyncio.sleep(seconds)
    text = f"waited {seconds}s"
    return text, len(text)

脚本的执行方式 ​

脚本被当作自包含的单个 .py 文件加载,因此:

  • 不支持相对导入:from . import xxx 会报 attempted relative import with no known parent package;
  • 不能导入同目录中的其它模块:脚本所在目录不会加入 sys.path,import xxx 找不到同目录的 .py 文件;标准库与已安装的第三方库的绝对导入不受影响;
  • 脚本不以 __main__ 模块执行,if __name__ == "__main__": 中的代码不会运行;
  • __file__ 是脚本的绝对路径,可以用 Path(__file__).parent 读取脚本同目录下的数据文件;
  • 脚本的标准输出与标准错误(即 print() 的输出、写入 sys.stderr 的内容)不会出现在运行日志面板中,而是写入软件的后台日志文件:标准输出记为信息级,标准错误记为错误级。日志面板与运行实例绑定,而所有运行实例共用一个 Python 解释器,无法判断输出来自哪个运行实例,因此脚本的输出统一记入后台日志;
  • 脚本默认按 UTF-8 解码,也可以用文件头的编码声明(PEP 263)指定其它编码;
  • 不会生成 __pycache__,项目目录中不会写入 .pyc 文件。

加载与缓存 ​

  • 每次运行程序都会重新读取脚本文件,因此修改脚本后无需重启软件,再次运行即可生效;
  • 同一次运行中,同一个脚本只会加载一次:模块级变量在本次运行内一直存在,多次调用会沿用上一次的模块状态;不同的运行(包括不同的执行器)之间互不影响。

在图形程序中调用 Python 程序 ​

与图形程序一样,Python 程序可以通过“调用程序”节点调用:节点上的输入连接器来自被调用程序的输入选项,输出连接器来自输出选项。因此常见的做法是把 Python 脚本包装成 Python 程序,再在图形程序中按需调用。

限制 ​

  • Python 面板不提供“停止”按钮:无法中断正在执行的 Python 函数,如果脚本中存在长时间不返回的循环或阻塞调用,需要等这次调用结束;
  • 脚本只能是一个文件,不能按包的形式拆分为多个文件(见脚本的执行方式)。