EP05 · 讲义
Genesis2000 Python 脚本实战 · 第5集 Main 主类——所有脚本的入口
本集学什么
- 零基础可懂
- 学完理解整个包怎么「拿起来就用」
- 全部代码有出处
这集收官核心四层。Main 类很小,我们把它一百零九行全部读完——不是挑重点,是全部。 读完你会发现:小文件里有大学问,每个设计都对着一个实际问题。
回顾:四层地图
前四集走完了下面三层:通信、查询、命令封装。它们的能力已经全部就绪。 还缺一个「总开关」——脚本怎么一步拿到全部能力。这就是 Main 类的角色。
定位:薄薄的入口
class Main(LcmClasses.MainLCM)
- 109 行 · 三分之一是注释
- 实例化一个 Main = 拿到整个开发包
Main 继承 MainLCM,所以前三层讲的全部能力它天然拥有。 它自己的代码只有一百零九行,其中还有三分之一是注释。脚本只要实例化一个 Main,就拿到了整个开发包。
实例化第一二件事:互逆映射表
self.number_hash = {"10": "a", "11": "b", ...} # 数字 → 字母self.letter_hash = {"a": 10, "b": 11, ...} # 字母 → 数字- 层序号超过 9 用字母续编:10→a … 35→z
- 一行字典查询完成转换
实例化时做了三件事。第一和第二,是一对互逆的映射表——数字序号和字母代号的互相转换。 这两张表解决一个很实际的问题:Genesis 的层序号超过九之后用字母续编——十对应 a,十一对应 b,一直到三十五对应 z。 脚本处理层序时经常要在两种表示之间转换。有了表,一行字典查询就完成,不用写一堆条件判断。
第三件事:用户表(平台分支)
if platform 是 Linux:
读 GENESIS_DIR/share/users
NAME= 取用户名
其后第 5 行 REAL_NAME= 取姓名
- Windows 下不构建用户表
- 注释:修一个报错时改出来的
第三件事,在 Linux 服务器上读取用户文件,建立用户名到真实姓名的字典,给界面程序做用户下拉列表用。 解析方式很有意思:读到 NAME 开头那行取用户名,往后数五行取真实姓名。旁边注释写着:这是修一个报错时改出来的。
注释掉的错误码表
- 曾计划读 ALL_ERRS 建错误码→说明字典
- 2024-12-17 的注释
文件里还有一整段被注释掉的代码:计划读取系统错误码文件,建立错误码到说明文字的字典,让脚本报错时显示人类可读的信息。 它最终没有启用,但注释里留着日期和意图。读老代码时,注释掉的段落常常藏着「当时想做什么」的线索。
PATHS:集中路径配置(完整源码)
_SCRIPTS_ROOT = "/genesis/sys/scripts"
PATHS = { "fast_system_root": f"{_SCRIPTS_ROOT}/<内部系统>", "add_pcs_num": f"{_SCRIPTS_ROOT}/<生产系统>/<拼板模块>/add_pcs_num.py", "<生产系统>": f"{_SCRIPTS_ROOT}/<生产系统>", ...
}
- 注释原话:集中管理,替代各模块硬编码路径
- 键名即业务语义
第四个设计是 PATHS:把跨系统脚本的路径集中到一个字典里,注释写得很直白——集中管理,替代各模块硬编码路径。 看看里面装了什么:内部系统的根目录和配置目录,两个跨系统脚本的完整路径,还有生产系统的导入路径。 每个键名都是业务语义——要用哪个系统的脚本取哪个键。路径细节被语义取代了。
restart_program:原地重启(完整源码)
def restart_program():
_python = sys.executable
os.execl(_python, _python, *sys.argv)
- 原地重启:进程无缝替换,任务不中断
- 无人值守脚本的标配武器
还有一个小而实用的函数:restart_program。它用 exec 系统调用,原地重启当前脚本,命令行参数原样保留。 自动化任务长时间运行、状态异常时,重启自身是最简单的自愈手段——进程被新进程无缝替换,任务不中断。无人值守脚本的标配武器。
双通道设计
Do = Main()
Do.openjob(...) # 写法一
Do.do.openjob(...) # 写法二:等价
- 内部再挂一个 MainLCM 在 do 属性
- 老代码两种风格混着出现,不要奇怪
再讲一个读代码必须知道的设计:双通道。Main 实例化时,内部又实例化了一个 MainLCM 挂在 do 属性上。 所以 Do 点方法名、和 Do 点 do 再点方法名,两种写法等价。老代码里两种风格混着出现,不要奇怪——它们指向同一套能力。
使用全景:所有脚本的共同开头
from MainClasses import Main
Do = Main()
- 从此拥有:通信 / 查询 / 120 个命令 / 工具方法
- 四层架构存在的全部意义
把这十集串起来:导入 Main,实例化成 Do——从这一刻起,通信层的协议细节、查询层的中文类别、命令层的四步套路,全部就绪。 你只需要关注业务:要开料号就调开料号,要查矩阵就查矩阵。这正是四层架构存在的全部意义。
使用案例巡览
Do.get_job_lock_list() # 查锁定列表
Do.getunits() # 查当前单位
Do.StepList('job') # 查料号的 step 清单- 摘自包内 docstring「使用例子」原文
- 下一集:JobClasses 料号业务
最后看真实用法。这三个例子摘自包内文档:查锁定列表、查当前单位、查步骤清单,全是一行。 从下一集开始,我们走出核心四层进入业务模块。第一站:JobClasses——料号信息获取,三千五百行的业务封装,也是整个包里真正的「干活主力」。
小结与预告
- 入口薄、设计厚:映射表 + 集中配置 + 自愈重启 + 双通道
这一集收官了核心四层。Main 类虽然薄,但每个设计都对着实际问题。 下一集进入业务模块:JobClasses 料号信息获取。它怎么把 ERP 数据、Genesis 本体、防呆规则统一起来,我们下集见。
零壹AI工作室出品 · 《用 Python 驱动 Genesis2000》免费公开课 · www.binwindai.com