PyCharm插件开发实践之PyGetterAndSetter详解
背景需求
在面向对象的设计中,典型如Java语言,为了控制对象属性的修改入口,我们常用的做法是把属性设置为private,然后通过getter和setter方法访问、修改该属性。
但是在Python语言中,并没有Java的访问控制符,对象的属性可以直接访问、修改。
为了良好的设计规范,我们可以规定,在Python类中,所有的对象属性均以下划线"_"前缀开头,同时编写该属性的getter和setter方法,在其他地方引用的时候,禁止出现直接引用。
在IDEA等IDE中,可以对Java的对象属性直接生成getter和setter方法,但是针对Python没有这样的功能。大量的getter和setter方法,很耗费精力,所以需要一款插件来辅助自动化生成Python对象属性的getter和setter方法。
搭建环境
编写IDEA系列的插件开发环境,可以看我之前的一篇文章:《IntelliJ IDEA/Android Studio插件开发指南》
官方开发文档:IntelliJ Platform SDK
过程拆解
Python文件例子:
class Test(object): def __init__(self): self._var1 = "" self._var2 = 0
明确了需求、输入(python对象属性定义代码)、输出(PyCharm插件自动生成getter和setter)后,我们针对这个插件的流程进行拆解:
- 首先,用户选中了对应行的文本内容,插件获取到该内容文本
- 在内容文本中过滤出变量,在本例中,就是过滤出_var1, _var2
- 拼装变量的getter和setter方法
- 计算出要插入的位置
- 回写到编辑器中
1. 获取文本
在PyCharm插件中,Editor对象是编辑器的总览,其中包含很多Model,比如
CaretModel caretModel=editor.getCaretModel(); // 用于描述插入光标 SelectionModel selectionModel = editor.getSelectionModel(); // 用于描述选中的文本 FoldingModel foldingModel = editor.getFoldingModel(); // 用于描述代码折叠区域 IndentsModel indentModel = editor.getIndentsModel(); // 用于描述缩进 ……
在这里,我们只需要SelectionModel。
// 获取光标选中文本段对象 SelectionModel selectionModel = editor.getSelectionModel(); // 拿到选中部分字符串 String selectedText = selectionModel.getSelectedText();
2. 正则匹配
拿到选中文本后,有可能选择了多行,里面包含多个变量,所以我们需要获取到变量列表。
观察到所有的变量都是self.abc=xxx
的模式,我们可以考虑用正则匹配把其中的abc
获取到。
Java中负责正则匹配并获取匹配字符串的类是Pattern
和Matcher
。
/** * 获取选中文本中所有的self.value中的value <br> * e.g. self.value = xxx,or self._value = xxx, <br> * 可以获取到其中的value * * @param selectedText 选中文本 * @return 变量字符串列表 */ public ArrayList<String> getFieldList(String selectedText) { ArrayList<String> list = new ArrayList<>(); // 删除所有空格 selectedText = selectedText.replaceAll(" ", ""); // 正则匹配获得变量字符串 String reg = "self.(.*?)="; Pattern pattern = Pattern.compile(reg); Matcher matcher = pattern.matcher(selectedText); while (matcher.find()) { list.add(matcher.group(1)); } return list; }
3. 拼装方法
Python中的getter和setter方法都非常简单,我们可以先创造一个模板:
// 定义Getter和Setter的模板 String getterTemplate = " def get_word(self):\n return self.field\n "; String setterTemplate = " def set_word(self, word):\n self.field = word\n ";
之所以存在空格,是为了匹配PyCharm的缩进,我这里使用的4个空格做缩进,如果你使用两个空格的话,在这里修改成两个空格即可。
在这里不能使用\t
,我尝试了\t
,在PyCharm中无法自动转换为4个空格,会报错。
上一步获取到的变量,有可能不存在下换线前缀,也有可能存在1个或者2个下划线前缀,比如var
,_var
,__var
,他们对应的gett和setter如下:
# 假如变量为_var def get_var(self): return self._var; def set_var(self, var): self._var = var;
可以看到在self.xxx
中需要使用变量,而在get_xxx
和setter的参数中,需要删除对应的下划线。所以有:
…… // 对于 “_value” 类型的变量,在set方法参数中,只需要“value” for (String field : fieldList) { String tmp = field; int i = 0; while (tmp.charAt(i) == '_') { tmp = tmp.substring(1); } // 替换掉模板中的变量 String customGetter = getterTemplate.replaceAll("word", tmp).replaceAll("field", field); String customSetter = setterTemplate.replaceAll("word", tmp).replaceAll("field", field); stringBuilder.append("\n").append(customGetter).append("\n").append(customSetter); } ……
4. 计算位置
首先需要获取到Document对象,这是负责描述文档的,里面有很多负责文档的方法,比如在文件中插入字符串,计算文件行数,计算文档长度,删除相应内容等等。
Document document = editor.getDocument();
为了方便简单,我们设定在选中文本的下一行生成getter和setter。
// 得到选中字符串的结束位置 int endOffset = selectionModel.getSelectionEnd(); // 得到最大插入字符串(生成的Getter和Setter函数字符串)的位置 int maxOffset = document.getTextLength(); // 计算选中字符串所在的行号,通过行号得到下一行的第一个字符的起始偏移量 int curLineNumber = document.getLineNumber(endOffset); int docLineCount = document.getLineCount(); // 如果目前文件行数不足以支持选中文本的下一行,也就是选中文本包含最后一行,就插入一个空行 if (docLineCount - 1 < curLineNumber + 1) { Runnable runnable = () -> document.insertString(maxOffset,"\n"); WriteCommandAction.runWriteCommandAction(project, runnable); } int nextLineStartOffset = document.getLineStartOffset(curLineNumber + 1);
5. 回写
将字符串插入文档中,不能直接使用document.insertString
,会error: Assertion failed: Write access is allowed inside write-action only (see com.intellij.openapi.application.Application.runWriteAction())
需要把这个任务放入一个Runnable中,然后由WriteCommandAction
来调度。
参考:Write access is allowed inside write-action only
// 对文档进行操作部分代码,需要放入runnable,不然IDEA会卡住 Runnable runnable = () -> document.insertString(nextLineStartOffset, genGetterAndGetter(fieldList)); // 加入任务,由IDE调度任务 WriteCommandAction.runWriteCommandAction(project, runnable);
效果
目前来看效果还不错,关于安装方法、使用方法,见github的README。
资源
github链接:https://github.com/mybichu/PyGetterAndSetter
到此这篇关于PyCharm插件开发实践之PyGetterAndSetter详解的文章就介绍到这了,更多相关PyCharm插件开发内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
相关文章
- 今天小编就为大家分享一篇解决Pycharm的项目目录突然消失的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-22
- pycharm2021激活码是一个可以轻松帮助用户免费激活pycharm2021.1软件的文件,虽然说pycharm现在只是推出了2021.1的EAP版,但是如果你想先率先体验一波,那么就可以利用小编提供的这个激活码来进行使用啦,并这个激活码是永久有效的...2021-03-30
- 这篇文章主要介绍了pycharm实现print输出保存到txt文件,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-02
- 这篇文章主要介绍了pycharm 实现光标快速移动到括号外或行尾的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-06
- 这篇文章主要介绍了解决Pycharm 运行后没有输出的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-06
pycharm最新免费激活码分享(无须破解,复制粘贴即可 21.4.20亲测可用)
这篇文章主要介分享了pycharm的最新激活码,帮助大家更好的免费使用此IDE,感兴趣的朋友可以了解下...2021-04-20- 这篇文章主要介绍了在PyCharm中安装PaddlePaddle的方法,本文给大家介绍的非常想详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-05
- 这篇文章主要介绍了Pycharm 设置默认解释器路径和编码格式的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05
详解pycharm的python包opencv(cv2)无代码提示问题的解决
这篇文章主要介绍了详解pycharm的python包opencv(cv2)无代码提示问题的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-29- 这篇文章主要介绍了Pycharm 跳转回之前所在页面的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05
- 这篇文章主要介绍了Pycharm 如何一键加引号的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-05
- 这篇文章主要介绍了pycharm激活方法到2099年,文末给大家提到了idea和pycharm最新版激活方法,非常不错对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-09-15
- 这篇文章主要介绍了基于Pycharm加载多个项目过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-04-22
解决pycharm下载库时出现Failed to install package的问题
很多小伙伴遇到pycharm下载库时出现Failed to install package不知道怎么解决,下面小编给大家带来了解决方法,需要的朋友参考下吧...2021-09-04- 这篇文章主要介绍了PyCharm设置注释字体颜色以及是否倾斜的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-16
- 这篇文章主要介绍了pycharm 复制代码出现空格的解决方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-16
基于Python-Pycharm实现的猴子摘桃小游戏(源代码)
这篇文章主要介绍了基于Python-Pycharm实现的猴子摘桃小游戏,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-20- 这篇文章主要给大家分享我对JS插件开发的一些感想和心得的相关资料,需要的朋友可以参考下...2016-02-09
- 从这一节开始,我们将从零开始打造我们的chrome插件工具库,第一节我们将讲一下插件开发的基础知识并构建一个简单但却很实用的插件,在构建之前,我们先简单的了解一下插件以及插件开发的基础知识...2020-10-03
- 这篇文章主要介绍了pycharm 多行批量缩进和反向缩进快捷键介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-16