Python 插件式程序设计与开发实践总结

Python 插件式程序设计与开发实践总结[Python基础]

插件式程序设计与开发实践总结

By:授客 QQ:1033553122

开发环境

win 10

python 3.6.5

 

代码结构

 

 

 

 

需求描述

如上,以user.py为程序入口脚本,运行该脚本时,需要创建一个user类对象,执行一系列动作(包含一系列动作的列表)。程序执行动作前,要求先获取动作名称,根据该名称,执行不同的操作。这些操作,对应不同的类函数。

 

 

实现思路

大致实现思路就是,把user对象需要运行的类函数(使用@classmethod修饰的函数,可不用创建对象进行调用),当作插件函数,并设置为user的属性,这样程序运行时,可通过该属性来调用对应的类函数。这里的问题是,程序怎么知道执行哪个类函数呢?到目前为止,程序只能根据动作名称来判断待执行的操作,所以,需要建立动作名称和类函数的映射关系。

 

怎么建立动作名称和类函数的映射关系呢?这里用到了装饰器,新建一个装饰器类ActionDecorator,为该类设置一个字典类型的类属性ACTION_FUNC_CLASS_MODULE_MAP,用这个类来存放动作名称和类函数的映射关系。我们把需要当作插件函数的类函数都用该装饰器进行修饰。

 

这里,笔者发现一个特性,就是对应模块被导入时,对应模块,对应类函数如果使用了装饰器,该装饰器函数会被执行。同时,笔者还发现另外一个特性,

首次对某个包执行import操作时,该包下面的__init__.py文件将优先被执行。基于这两个特性,我们把装饰器放在用于管理插件类函数的外围软件包下(例中的components包),同时,在该外围软件包下的__init__.py中加入动态加载插件模块的代码:遍历外围软件包下的所有非__init__.py文件,并且动态加载改模块。这样,当在user.py入口文件中,执行from components.decoraters.action_decorater import ActionDecorator时,会自动执行components/__init__.py文件,动态加载所有插件模块,并且自动触发装饰器的执行,装饰器方法执行,会自动根据提供的方法参数建立动作名称和类函数的映射关系。

 

然后,在初始化user对象时,给该对象动态设置属性,属性名称设置为动作名称,属性值设置为类方法,这样,执行动作时,就可以根据动作名称调用对应的类方法了。

 

 

代码实现

 

 

action_decorate.py

 

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-


"""
@CreateTime: 2020/12/09 14:58
@Author : shouke
"""

class ActionDecorator(object):
    """
    action 装饰器
    """

    ACTION_FUNC_CLASS_MODULE_MAP = {}

    @classmethod
    def action_register(cls, action, class_name, function_name, module_path):
        def wrapper(func):
            cls.ACTION_FUNC_CLASS_MODULE_MAP.update({action: {"class_name":class_name, "function_name":function_name, "module_path":module_path}})
            return func
        return wrapper
hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » Python 插件式程序设计与开发实践总结