Python宿主集成
全库目录221
本文目录7
系统解释器能导入的扩展,在DCC内可能加载失败;后台计算已经完成,写回时用户又可能换了场景。Python宿主集成需要同时匹配解释器二进制环境与宿主对象的操作期间。先确认程序实际运行在哪里,再安排计算和提交的边界。
解释器与扩展加载
DCC通常内嵌指定版本的Python,并带自己的模块、动态库与Qt绑定。工具启动时先在宿主运行下面的标准库探针,记录解释器路径、完整版本和机器架构;导入目标模块后再输出它的__file__,确认实际加载来源。
import sys
import platform
print(sys.executable)
print(sys.version)
print(platform.machine())导入分两层:sys.path决定能否找到模块文件,本机扩展的ABI与依赖则决定文件能否加载。假设系统使用一种CPython版本,DCC使用另一种版本,复制系统的扩展文件到宿主搜索目录,可能从“找不到模块”变成“动态库加载失败”。路径已经正确,继续增加搜索路径并不能改变扩展内部使用的解释器ABI。
因此依赖清单应固定宿主版本、PythonABI、平台架构、扩展wheel、Qt绑定及依赖库。项目通过受控包目录或启动器注入路径,包内容按哈希固定;宿主升级时在相应环境重新验证导入。混用不同Qt绑定还可能带入不兼容对象与事件循环,不能只看顶层import是否成功。
宿主上下文与批量数据
某些命令依赖当前选择、模式或活动窗口。批处理若假定用户正选中目标对象,用户改变选择就会把同一脚本作用到另一个对象。工具先按稳定ID解析对象,校验类型与编辑状态,再使用显式数据接口修改。确需操作符上下文时,保存、建立并恢复上下文,异常分支也执行恢复。
高频逐点绑定调用会反复执行类型转换与跨语言跳转。处理一百万顶点时,可先用宿主批量接口读出连续数值数组,在纯数据上计算,再批量写回。计算期间不保留可随编辑失效的宿主内部指针;读出的快照附带场景与对象版本,写回时核对它仍对应同一份几何。
后台计算与主线程提交
常规带GIL的CPython线程通常不能并行执行CPU密集字节码。IO等待或释放GIL的原生库可以利用线程,纯Python计算可考虑进程,但需要序列化与启动成本。CPython3.13开始提供可选自由线程构建,是否启用及扩展是否兼容由实际解释器决定;它也不会解除DCC自己的场景API线程要求。
把一份网格快照交给后台时,任务只持有数值与ID,并记录sceneVersion与meshVersion。后台返回后排到宿主允许的线程,重新解析目标、核对版本,再提交变更:
主线程:解析对象42,读取顶点,记录scene=7、mesh=12
后台:只计算快照数据,返回结果及上述版本
主线程:重新找到对象42
若场景非7、对象不存在或mesh非12:丢弃或重新计算
否则:以宿主事务批量写回,记录新mesh版本假设后台期间用户删除42又导入新网格。只保存显示名称可能命中新对象,裸指针可能已失效;稳定ID加版本检查使这份旧结果被拒绝。用户只是修改了顶点,也会改变mesh版本,此时直接写回会覆盖人工修改,应重算或使用明确的合并规则。
取消、退出与验证
关闭面板先停止新任务,注销待提交回调并请求后台取消,再等待持有快照或文件的工作结束。无法立刻停止的计算可以继续完成,但它的结果必须通过失效令牌被丢弃。宿主退出后仍调用场景API的回调,常把正常取消变成崩溃;线程生命周期与面板可见性因此不能共用一个布尔值。
验收分别测试系统解释器与目标宿主导入、没有活动选择的批处理、计算期间切换场景、删除与重建对象、修改版本和关闭面板。记录实际解释器与模块路径,并核对每次提交接受或拒绝的原因。
实现与证据
探针是完整标准库代码;后台流程是带ID与版本的机制协议。现有机制实验在Python3.11运行,未在Maya或Blender宿主执行。PEP703支持自由线程机制说明,目标宿主的线程与撤销契约仍以其版本文档及接入实验为准。
相关主题
参考资料
- PEP703:Build Configuration Changes与扩展兼容;2026-10-22核读。
- Python Extending and Embedding:嵌入解释器与扩展接口。