开发必备知识点---根据字符串导入模块并且找到类

 1 import importlib
 2 
 3 # 根据字符串 找到导入的模块和类
 4 
 5 # 在同级目录下创建xxx.py文件,然后通过python的importlib模块导入
 6 m = importlib.import_module('xxx')
 7 
 8 # 导入过来后执行了xxx.py文件的print()   根据字符串导入模块
 9 
10 print(m)  # <module 'xxx' from 'D:\学习历程\老男孩\第七模块\pro_crm\rbac\xxx.py'>
11 
12 cls = getattr(m, 'Foo')
13 print(cls)  # <class 'xxx.Foo'>
14 
15 # 实例化一个对象
16 obj = cls('江子牙')
17 
18 # 执行对象的方法
19 obj.func()  # 江子牙
20 
21 # 根据path导入该模块
22 RBAC_USER_MODEL_CLASS = 'x.xxx.X'
23 
24 # 获取模块名称和类的名称
25 module_path, model_class_name = RBAC_USER_MODEL_CLASS.rsplit('.', maxsplit=1)
26 
27 print(module_path, model_class_name)
28 
29 m = importlib.import_module(module_path)
30 
31 cls = getattr(m, model_class_name)

django也有个模块有这个功能,其实内部就是通过上面实现的。

1 from django.utils.module_loading import import_string
2 
3 m = import_string('xxx.Foo')
4 print(m)
5 
6 # 根据字符串导入模块
7 # <class 'xxx.Foo'>

这个功能强大之处就是遵循了开放封闭原则。

对代码封闭、对配置开放。

可以通过配置文件。

djang的配置文件就是这样做的

如果公司需要开发一个短信提醒功能,但是目前只支持三种,通过配置字符串,就可以不修改源代码,来扩展短信提醒的方式。

创建run.py

 1 #! /usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # __author__ = "ziya"
 4 # Date: 2018-12-21
 5 
 6 import settings, importlib
 7 
 8 
 9 def excute():
10     """
11     消息提醒功能
12     :return: 
13     """
14     for path in settings.SEND_MSG_LIST:
15         module_path, class_name = path.rsplit('.', maxsplit=1)
16         m = importlib.import_module(module_path)
17         cls = getattr(m, class_name)
18         obj = cls()
19         obj.send()
20 
21 
22 if __name__ == '__main__':
23     excute()

同级目录下创建settings.py

 1 #! /usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # __author__ = "ziya"
 4 # Date: 2018-12-21
 5 
 6 SEND_MSG_LIST = [
 7     "message.email.Email",
 8     "message.weixin.WeChat",
 9     "message.duanxin.MobileMsg",
10 ]

再创建一个包存放各个消息提醒的模块

messagexxx.py

# email.py
class Email(object):

    def send(self):
        print('发送邮件')

# weixin.py
class WeChat(object):

    def send(self):
        print('发送微信')

# duanxin.py
class MobileMsg(object):

    def send(self):
        print('发送短信')

执行run文件。

此时加钉钉消息提醒功能的话,去包里写好钉钉这个功能的模块。

dingding.py

class DingDing(object):

    def send(self):
        print('发送钉钉')

也只需再配置文件里配置。

1 SEND_MSG_LIST = [
2     "message.dingding.DingDing",
3 ]

 run的源代码并没有修改,但是执行的时候,功能却扩展了。如果不想要哪个功能,在配置文件里注释即可。遵循了开放封闭原则。

原文地址:https://www.cnblogs.com/xjmlove/p/10155547.html