开发必备知识点---根据字符串导入模块并且找到类
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 ]
再创建一个包存放各个消息提醒的模块
message\xxx.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的源代码并没有修改,但是执行的时候,功能却扩展了。如果不想要哪个功能,在配置文件里注释即可。遵循了开放封闭原则。