首先我们看到Carrier
基类里:
出现了一个奇怪的1=TakeoffMode()
,这无疑是因为我们类图里那个组合关系设置的1对1惹的祸,看来是不能那样设置的,与此同时,takeoffMode=null
也存在问题,在Python中null
是应该写作None
,而且也不能这样定义对象属性。
首先我们在类图中的组合关系上删除错误的1对1表示:
然后在基类Carrier
的属性中设置为抽象类:
我们现在还有类不能正确创建对象属性和构造函数的问题,这需要我们修改默认的代码生成模板。
关于代码生成模板的介绍,可以看,这个火龙果好像是一个专业的EA培训机构,缺点是要钱。
点击develop>Options>Edit Code Template:
第一个模板file
用于在自动生成的代码前添加注释,我们可以按自己的需求修改:
不用担心修改后找不到原始模板内容,右下角有Get Default Temp...
。
关于CTF(Code Template Framework)的官方介绍可以看。
需要注意的是每修改完一个模板,要ctrl+S保存才能生效。
模板修改页面最下边的一条是会被windows任务栏遮住的,只有隐藏任务栏才能看到,不过这一条的按钮可有可无,用处不是很大,类似的小毛病EA比比皆是,大概专用软件都是这个样子吧,不鸟用户还能卖的死贵。
接下来我们要修改类,以符合Python的类定义:
这里主要是添加了一个构造函数,在构造函数内定义属性。
代码我贴出来吧:
def __init__(self): $attr=%list="Attribute" @separator="\n" @indent=" "% %if $attr == ""% pass\n %endIf% $ops=%list="Operation" @separator="\n\n" @indent=" "% $iclasses=%list="InnerClass" @separator="\n\n" @indent=" "% %if $iclasses != ""% $iclasses\n %endIf% $attr $ops %if $attr == "" and $ops == "" and $iclasses == ""% pass %endIf%
类似的,还要修改属性声明:
这个简单,只是原本模板只考虑了private,没有考虑protected,照葫芦画瓢即可。
最后还要修改方法声明:
这里主要是在方法参数最前面加入self
,真心觉得EA对Python的支持就是个半成品,还好模板支持自定义。
修改后的模板如下:
$dec=%REPLACE(opTag:"decorators","@","\n@")% %TRIM($dec)% %PI=" "% $params = %list="Parameter" @separator=", "% def %PI=""% %if opScope == "Private"% __ %else if opScope == "Protected"% _ %endIf% %opName% %if $params == ""% (self): %else% (self, $params): %endIf%
最后还发现只要有组合关系存在,EA在生成代码时候会给属性添加上一个m_takeoffMode=TakeoffMode()
,这显然是不合适的,直接删除组合关系:
然后按中的步骤生成代码。
到这里用EA生成的Python框架代码已经能用了,但还谈不上完美,我这里尝试了一下加入抽象类和抽象方法的支持,先修改类声明的模板:
判断如果是抽象类,就自动引用abs模块,具体代码如下:
$classAbstract=%classAbstract% %if $classAbstract == "T"% from abc import ABCMeta, abstractmethod\n %endIf% $dec=%REPLACE(classTag:"decorators","@","\n@")% %TRIM($dec)% class %className%%ClassInherits%:
再修改类继承模板:
如果是抽象类,就在继承参数中加入metaclass=ABCMeta
,具体模板代码如下:
%PI=""% $bases=%list="ClassBase" @separator=", "% $interfaces=%list="ClassInterface" @separator=", "% $classAbstract=%classAbstract% %if $classAbstract == "T"% %if $bases != ""% $bases="metaclass=ABCMeta"+$bases %else% $bases="metaclass=ABCMeta" %endIf% %endIf% %if $bases != "" and $interfaces != ""% ($bases, $interfaces) %elseIf $bases != ""% ($bases) %elseIf $interfaces != ""% ($interfaces) %endIf%
最后修改方法声明:
判断如果是抽象方法,就在方法上面加入抽象方法修饰器,具体模板代码如下:
$opAbstract=%opAbstract% %if $opAbstract == "T"% @abstractmethod %endIf% $dec=%REPLACE(opTag:"decorators","@","\n@")% %TRIM($dec)% %PI=" "% $params = %list="Parameter" @separator=", "% def %PI=""% %if opScope == "Private"% __ %else if opScope == "Protected"% _ %endIf% %opName% %if $params == ""% (self): %else% (self, $params): %endIf%
现在再运行生成代码步骤,可以看到抽象类和抽象方法都完美支持:
还有个小瑕疵,构造函数内有属性赋值的时候,最后不会换行,不过应该无伤大雅。
生成代码中的模块引用使用的是绝对路径,不知道能否改为相对路径,这里我不打算继续折腾了,如果有知道怎么改的可以留言告诉我一下,不胜感激。
短期内我是不会再更EA15的使用指南了。写这部分是真心累,相关中文资料是真的少不说官方文档也是极为简略。
最后附上我的EA工程文件,想试一下用EA生成代码的可以用来做测试:
百度盘:
链接:https://pan.baidu.com/s/1IJZK3lZk5aKNt3uZCtZ4qg 提取码:0hao
文章评论