我的编程空间,编程开发者的网络收藏夹
学习永远不晚

PyCharm插件开发实践之PyGetterAndSetter详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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)后,我们针对这个插件的流程进行拆解:

  1. 首先,用户选中了对应行的文本内容,插件获取到该内容文本
  2. 在内容文本中过滤出变量,在本例中,就是过滤出_var1, _var2
  3. 拼装变量的getter和setter方法
  4. 计算出要插入的位置
  5. 回写到编辑器中

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中负责正则匹配并获取匹配字符串的类是PatternMatcher


  
    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插件开发内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

PyCharm插件开发实践之PyGetterAndSetter详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

十大CMS插件开发最佳实践

CMS插件开发是一项复杂且艰巨的任务,需要考虑许多因素。本文总结了,帮助您开发出高质量的CMS插件。
十大CMS插件开发最佳实践
2024-02-14

gRPC实践之proto及Maven插件概念及使用详解

这篇文章主要为大家介绍了gRPC实践之proto及Maven插件概念及使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-16

CMS插件开发 与网站安全:最佳实践

CMS插件开发与网站安全:最佳实践
CMS插件开发 与网站安全:最佳实践
2024-02-15

Android开发之TimePicker控件用法实例详解

本文实例分析了Android开发之TimePicker控件用法。分享给大家供大家参考,具体如下: 新建项目: New Android Project-> Project name:HelloSpinner Build Target:Andr
2022-06-06

CMS插件开发 最佳实践:提升效率和性能

CMS 插件开发最佳实践:提升效率和性能
CMS插件开发 最佳实践:提升效率和性能
2024-02-15

umi插件开发仿dumi项目加载markdown文件实现详解

这篇文章主要为大家介绍了umi插件开发仿dumi项目加载markdown文件实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-28

Android开发之文件操作详解

本文实例讲述了Android开发之文件操作。分享给大家供大家参考,具体如下:目前,几乎所有的设备都会涉及到文件的操作,例如什么电脑,手机等设备。Android的文件操作和电脑是比较类似的,既可以存储在手机内置的存储器里也可以是sd卡。在这篇
2023-05-30

Android 开发之旅:详解view的几种布局方式及实践

引言 我们对Android应用程序运行原理及布局文件可谓有了比较深刻的认识和理解,并且用“Hello World!”程序来实践证明了。在继续深入Android开发之旅之前,有必要解决前两篇中没有介绍的遗留问题:View的几种布局显示方法,以
2022-06-06

umi插件开发仿dumi项目实现页面布局详解

这篇文章主要为大家介绍了umi插件开发仿dumi项目实现页面布局详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-28

FlutterWidget开发之Focus组件图文详解

这篇文章主要为大家介绍了FlutterWidget开发之Focus组件图文详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-08

Sphinx搜索的扩展插件与定制化开发实践(如何为Sphinx开发扩展插件和定制功能?)

Sphinx扩展插件和定制化开发指南,详解扩展插件的创建和安装,以及定制化开发的实践。开发者可以通过扩展Sphinx的核心功能和直接修改源代码来增强其搜索功能,以满足特定需求。扩展插件相对易开发,而定制化开发则需要对Sphinx源代码有深入了解。根据具体要求,可选择适合的开发方式,优先考虑扩展插件,仅在必需时进行定制化开发。
Sphinx搜索的扩展插件与定制化开发实践(如何为Sphinx开发扩展插件和定制功能?)
2024-04-02

详解Android开发之MP4文件转GIF文件

一 基本实现原理在介绍具体实现过程之前,先简单说下基本原理和实现步骤,在解决相对比较复杂的问题,我习惯先理清主要原理步骤,不要一开始就被繁琐细节绊住,待具体实现时再逐个攻破。下面是主要步骤: 1、视频文件的读取:包括录制和本地文件
2022-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录