本文介绍了Python插件的开发过程,包括需求分析、开发思路设计、选定插件类型及事件、编写Python脚本、功能测试/调试、上线使用等步骤。还详细讲解了Python插件脚本代码的构成、开发IDE及语法注意事项,如缩进格式、代码结束符、全局变量等。此外,还提供了插件调试方法和常见错误说明,帮助开发者在开发过程中避免常见问题。最后,作者还建立了QQ交流群,鼓励学习者加入并持续学习Python插件开发。
往期回顾:
【Python插件入门】第1篇:Python插件入门讲解
大家好,我来更新第二篇啦。今天我们先学习一下Python插件的开发过程以及一些注意事项,这些都是最基本要了解和掌握的,内容也比较简单,作为一个入门的了解,下面开始正文。
一、Python插件的基本开发过程
需求分析:梳理业务需求,分析出需要开发解决的本质问题,并转化成对系统功能的需求描述。
开发思路设计:根据功能需求说明,进行整体的开发思路设计,确定二开业务对象、字段等,梳理出需要开发Python插件解决的问题点。选定插件类型以及要使用的事件(1个或多个)。
后续的讲解文章中会逐一介绍各类型插件和事件的用法,学习之后就知道如何选择合适的插件类型和事件。
编写Python脚本:根据选定的插件及事件进行功能实现脚本编码,不建议从0开始编写,建议复制一些已有的Python插件案例进行改写。例如,要开发一个表单插件,可以找一个已有的Python表单插件脚本进行修改,添加修改事件方法以及功能实现逻辑即可。
功能测试/调试:编写好Python插件脚本之后,在测试环境的BOS平台中进行注册,并通过BOS平台本身的语法检查后,进行功能测试,反复修改调整,直到功能完全达到预期效果。
建议使用测试环境进行测试和调试,Python插件测试环境很好建立,只需要复制一个数据中心即可作为测试环境。
如果确实不方便准备测试数据中心,例如公有云,也可以在Python脚本测试过程中,在代码逻辑中加入一些判断,只在测试数据的情况下执行脚本功能,例如,单据组织='测试组织编码'、创建人='测试用户'...等等。
上线使用:在正式环境的BOS平台中打开对应的单据,打开对应插件类型的注册位置,将测试好的Python脚本复制进行注册。如果是直接在正式环境进行测试的,取消测试的判断条件即可。
二、Python插件脚本代码构成"三部曲"
import clr:引入clr运行库,使用pythonnet的clr模块将dll类库导入。Python插件采用IronPython要用到dll类库必须使用导入这个模块。
类库引用(clr.AddReference):导入dll类库,相当于C#插件中添加dll文件引用。不懂C#的同学可理解成导入了一个文件夹。
命名空间引入(from...import*):引入dll类库中的某个类,'*'表示引入全部。相当于C#插件中的using。不懂C#的同学可以理解成从某个文件夹中导入了某一个文件。所以必须要引用类库,才能引入类库中的命名空间。
例如,C#插件中要使用DBServiceHelper执行SQL,要引入命名空间:using Kingdee.BOS.ServiceHelper;
Python插件中就是:from Kingdee.BOS.ServiceHelper import * ,注意:Python后面没有分号!
方法/函数定义(def):定义一个方法(也可以称为函数),通常在Python插件中表示我们要使用哪个事件,或者一个复杂的功能逻辑我们也可以自定义封装一个我们自己的方法,在事件方法中进行调用。
Python中如何封装自己的方法函数,请自行网上学习Python基础语法。参考:Python函数
下面看一个代码结构分解示例截图:
Q1:那么关键问题来了,做开发的时候我怎么知道要引用哪些类库,引入哪些命名空间呢?
这个目前没有什么技巧,我分享一下我是怎么解决这个问题的,这里确实需要一点C#插件基础了,所以没有这个基础的同学还是建议去学习一下,不一定学太深,至少知道每种插件类型怎么建工程和类文件。
A1:我一般是这样解决这个问题的:
插件有一些基本的类库是先引入进来,每次复制就行了,所以前面提到建议采用复制修改的方式进行Python插件开发。大家也不用太担心,后面具体插件的讲解过程中会给出Python示例,就有模板可以复制啦!
遇到特殊需要添加引用时,就把这段代码赋值到VS里面的C#插件工程中,VS工具会提示需要引如哪个命名空间,点击Using之后,VS会生成一行Using XXX的代码。
把Using后面的这一串复制进来,当然前提是这个插件工程已经添加了插件常用库文件的引用。常用库文件如下图。
大家可以用VS建一个插件工程,把这些dll文件引用进去,作为一个工具使用。
Q2:这里有同学会问了,VS会提示需要引用命名空间,Python插件开发怎么知道需要添加命名空间呢?
A2:在后面的Python插件常见错误说明中,会讲到哪种报错提示表示需要添加命名空间,接着往下看!
三、Python插件中的语法注意事项
一直没提到大家关注的问题,那就是开发IDE。简单提一下:Python属于脚本语言,所以一般直接在BOS平台中点开【注册Python脚本】,编辑Python脚本就可以了,方便快捷。如果有强迫症的同学也可以使用VS或者其他Python编码工具,甚至记事本都可以,Python语法对缩进格式要求严格,不要使用带格式的编辑器,例如Word、网页在线编辑等。
缩进格式:Python需要严格缩进对齐,尽量使用TAB键进行代码缩进对齐。
一行一码:Python脚本中一行只能写一句代码,不像其他开发语言,可以一行写多句,例如:a=1;b=2;必须写2行。
代码结束符:由于Python中一行就代表一句代码,所以可以不写任何结束符,当然,有强迫症,也可以用";"结束。
一级管一级:Python中没有大括号"{...}"来标记代码所属范围,如方法定义、循环体、条件判断等。
是完全通过缩进对齐来控制代码所属关系的,一定要注意!
例如,条件判断时,满足某个if条件执行下面的哪几行代码,是通过缩进对齐来控制的,只要在if的下一级,就表示满足 if才会执行。
缩进对齐属于逻辑问题,代码语法是不会报错的,但是功能效果达不到预期,就可以检查一下这个这一项。
当然,如果if下面一行代码都没有代码还是会报错的。
全局变量:Python中没有变量声明,对于全局变量,在方法外声明,在不同方法中引用全局变量时,通过global关键字进行声明。一定要先声明,再使用,否则系统会认为是方法体中的新变量。每个方法体中声明一次,不同方法体使用都要进行声明。如下图代码示例:
对象实例化:Python中没有new关键字,要实例化一个对象,相当于调用构造方法,例如 a=Student();
多行字符串常量:由于Python中一行只能写一句代码,那一个很长的字符串,就会横向拉得很长,例如一个长SQL预计,怎么拆分成多行呢?字符串首尾用【"""】标记即可,3个双引号!!!例如下面截图的SQL拼接代码:
模板类:把"<T>"改成"[T]",例如,C#中:var lst=new List<sting>()。Python插件中写成:lst=List[str]();
反射代理:C#插件中有时会用到反射代理类。在Python插件中将反射代理的类直接实例化进行使用。例如:
C#代码中:
IViewService viewService1 = Kingdee.BOS.Contracts.ServiceFactory.GetService<IViewService>(this.Context);
Python插件中写成:viewService1 =ViewService();当然,还需要引入ViewService类的命名空间。
语法注意就写到这里,都是一些常用的语法注意点,其他基础的语法需要补课,可以自行网上学习Python基础语法。
四、Python插件调试
Python插件调试在BOS中无法打断点跟代码,我一般用2种方法:
表单类插件(表单插件、列表插件):this.View.ShowMessage("提示信息");
服务类插件(服务插件、报表服务插件、单据转换插件):raise Exception("提示信息!");
更全的Python插件调试方法,@邱育华 老师已经做了一个分享,可以参考学习:附加进程调试Python代码
五、Python插件常见错误说明
BOS中编辑完脚本点击确定后,编译报错:
报错提示1:Could not add reference to assembly Kingdee.BOS.App
此报错可以忽略,这个是目前BOS平台的BUG。
报错提示2:unexpected token '<newline>'
不该出现换行的地方出现了换行,通常是需要打":"的地方没打,例如,if后面、方法定义后面等。
报错提示3:unexpected indent
缩进格式不对,通常是用空格敲了缩进,或者复制了网页的代码,格式混乱,重新用TAB键进行缩进。
报错提示4:unexpected token ':'、unexpected token ';'
代码中出现了非法字符,通常是误敲了中文冒号、分号等。
报错提示5:EOL while scanning single-quoted string
多行字符串常量定义有误,参考上面第三点中的多行字符串常量定义即可解决。
代码运行报错:
代码运行报错1:值“Microsoft.Scripting.Interpreter.InterpretedFrameInfo”不是“System.String”类型,不能在此泛型集合中使用。
代码中调用的类方法中出现了异常,系统无法解析,就会提示这个,通常是执行SQL报错,检查SQL即可,其他情况要针对具体的代码情况进行分析处理,通常也是调用某个类的方法时传入的参数有问题导致的。
代码运行报错2:global name 'DBServiceHelper' is not defined
"DBServiceHelper"没有定义,通常是没有引入对应的命名空间,也就是前面提到的需要添加命名空间引入。
代码运行报错3:No module named Core
引用的命名空间有错,不存在"Core ",请检查命名空间引入写法是否有误,或者缺少添加对应类库引用。
代码运行报错4:XXX is not Callable
XXX 不是一个方法,不能直接调用,一般是出现"XXX()"这种写法,去掉括号试试。
==========================本篇正文结束=======================================
写得比较细,内容较多,仔细阅读,我们先把基础知识打牢,不要急于写代码,后面很快就会到写代码的篇章。
大家持续关注,点赞、评论、收藏,您的点赞、评论就是我前进的动力。
下一篇:【Python插件入门】第3篇-插件中如何进行数据操作
第3篇参考学习:
知识共享 - 单据数据包DynamicObject的结构及操作
PS:为了更好的持续学习,借此机会新建QQ交流群:【550273071】,欢迎加入,大家一起来学习Python插件开发!