暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Python web框架 | 插拔式设计

程序媛小庄 2021-08-20
1614

在django全栈项目中,前端向后端提交post请求时需要注释csrf校验,将代码注释之后就无需进行校验了,如何实现只注释一行代码就可以注释掉整个功能呢?本文将介绍插拔式设计是如何实现的?


插拔式设计


插拔式设计实现需要借助一个模块importlib,该模块可以将字符串类型的路径转换为导入模块的语法格式。

    # 导入模块的常规写法
    from module import object


    # 使用importlib
    import importlib
    res = 'myfile.test'
    ret = importlib.import_module(res) # from myfile import b

    可以通过这种代码设计方式模拟一下通知消息,简约版微信 QQ 短信等同时发送,并且可以很方便的关闭某一种通知渠道。


    方式一:常规思路


    创建一个py文件,将每个功能定义为一个函数,再创建一个启动文件,将定义的功能导入,在启动文件中运行。

      myfile文件夹
      - notify.py


      def wechat(content):
      print(f'微信通知:{content}')




      def message(content):
      print(f'短信通知:{content}')


      def qq(content):
      print(f'qq通知{content}')


      - start.py
      import notify


      def send(content):
      notify.wechat(content)
      notify.message(content)
      notify.qq(content)


      if __name__ == '__main__':
      send('下课啦')


      1

      方式二:面向对象


      借鉴django中间件的思路,每个功能独享一个py文件,全部放在一个目录下。

      创建一个settings.py配置文件,将需要被导入的模块中的具体对象的路径以字符串的方式写入列表。

      在存放功能的文件夹下的每个py文件都是一个功能模块,所以该文件夹就是一个包,所以就需要在该文件夹下在创建__init__.py文件,将每一个功能模块的名字都放在该py文件下

      在__init__.py文件中,通过for循环 + 鸭子类型 +字符串方法+反射就可以实现django中settings.py中只需要添加注释或者解除注释就可以实现某种功能的添加或者删除

        # notify文件夹就是包
        - email.py


        class Email():
        def __init__(self):
        # 调用应用接口
        pass
        def send(self,content):
        print(f'email{content}')

        - qq.py
        class QQ():
        def __init__(self):
        # 调用应用接口
        pass
        def send(self,content):
        print(f'qq{content}')

        -wechat.py
        class Wechat():
        def __init__(self):
        # 调用应用接口
        pass
        def send(self,content):
        print(f'wechat{content}')



        - settings.py


        NOTIFY_LIST = [
        'notify.email.Email',
        'notify.qq.QQ',
        'notify.wechat.Wechat'
        ]


        - __init__.py


        import settings
        import importlib




        def send_all(content):
        for path_str in settings.NOTIFY_LIST: #'notify.email.Email'
        module_path,class_name = path_str.rsplit('.',maxsplit=1)
        # module_path = 'notify.email' class_name = 'Email'
        # 1 利用字符串导入模块
        module = importlib.import_module(module_path) # from notify import email
        # 2 利用反射获取类名
        cls = getattr(module,class_name) # Email、QQ、Wechat
        # 3 生成类的对象
        obj = cls()
        # 4 利用鸭子类型直接调用send方法
        obj.send(content)


        - start.py


        import notify
        if __name__ == '__main__':
        notify.send_all('haha')


        小庄卖瓜


        如果想要了解更多python知识,欢迎关注小庄微信公众号,我们一起学(zi)习(kua)吧~


        文章转载自程序媛小庄,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论