python 抽象类、抽象方法、接口、依赖注入、SOLIP

1、程序设计原则:SOLIP

SOLIP设计原则
  1、单一责任原则(SRP)
    一个对象对只应该为一个元素负责
  2、开放封闭原则(OCP)
    对扩展开放,修改封闭
  3、里氏替换原则(LSP)
    可以使用任何派生类替换基类
  4、接口分离原则(ISP)
    对于接口进行分类避免一个接口的方法过多
  5、依赖倒置原则(DIP)
    隔离关系,使用接口或抽象类代指
  6、依赖注入(DI)和控制反转原则(ICO)
    使用钩子再原来执行流程中注入其他对象

接口:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# =================================================以下是接口
class IorderRepository:  ##接口
    def fetch_one_by(self,nid):
        '''
        获取单条数据的方法,所有的继承呢当前类的类必须继承
        :param nid:
        :return:
        '''
        # raise Exception('子类中必须包含该方法')
class OrderReposititory(IorderRepository): #类
    def fetch_one_by(self,nid):
        print(nid)
obj = OrderReposititory()
obj.fetch_one_by(1)

抽象类抽象方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import abc
class Foo(metaclass=abc.ABCMeta):  ##抽象类
    def f1(self):
        print(123)
    def f2(self):
        print(456)
    @abc.abstractmethod  ##抽象方法
    def f3(self):
        '''
        ???
        :return:
        '''
class Bar(Foo):
    def f3(self):
        print(33333)
b = Bar()
b.f3()

抽象类, 抽象方法:

    抽象类中只能有抽象方法,子类继承抽象类时,不能通过实例化使用其抽象方法,必须实现该方法。py3引入了abc模块

class Foo(object):def exec(self):raise NotImplementedError('请实现exec方法')class A(Foo):pass
obj=A()
obj.exec()类A继承类Foo,因而拥有类Foo的所有属性。类A实例化一个对象obj,obj调用exec()方法,如果类A自己没有定义exec方法,就会主动抛出异常(raise)。

from abc import abstractmethod,ABCMetaclass Foo(metaclass=ABCMeta):@abcstractmethoddef exec(self):passclass A(Foo):pass
obj=A()从abc模块调用类abstractmethod和类ABCMeta,自己定义类Foo,继承抽象类ABCMeta,在类Foo中定义exec方法,并添加装饰器abcstractmethod。定义类A继承类Foo,并实例化对象obj,类A中必须有类Foo中的方法否则就会抛出异常。

组合:

class SqlHelper:def fetch_one(self):passdef fetch_all(self):passclass UserInfo:def __init__(self,helper):self.s = helperdef login(self):#数据库操作
        self.s.fetch_one()def logout(self):# 数据库操作
        self.s.fetch_one()def user_list(self):# 数据库操作
        self.s.fetch_all()h = SqlHelper()
obj = UserInfo(h)
obj.login()
#为了降低耦合,使代码减少依赖,将SqlHelper作为参数helper传递进去,两个类之间就没有直接依赖挂关系,叫做组合

引入依赖注入

解释器解释类的流程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# ======================================解释器解释类的流程===================
#  解释器解释:
# class Foo:
#     def __init__(self):
#         self.name =123
#     def f1(self):
#         print(self.name)
# 1.遇到class Foo,执行type的__init__方法
# 2.type的init的方法做什么呢!不知道
# obj =Foo()
# obj.f1()
# 3.执行Type的__call__方法
# 执行Foo类的__new__方法
# 执行Foo类的__init__方法

  

依赖注入在什么之前做什么操作

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyType(type):
    def __call__(cls, *args, **kwargs):  ##执行Type的__call__方法,这里的cls就是<__main__.Foo object at 0x001B59F0> Foo类
        obj = cls.__new__(cls, *args, **kwargs)  ##Foo的__new__方法
        print('-------------')
        obj.__init__(*args, **kwargs)  ##在执行Foo的__init__的之前做什么操作
        return obj
class Foo(metaclass=MyType):
    def __init__(self, name):
        print('============')
        self.name = name
    def f1(self):
        print(self.name)
obj = Foo(123)
print(obj)
print(obj.name)

  

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#=================================依赖注入案例一======================================
class MyType(type):
    def __call__(cls, *args, **kwargs):  ##执行Type的__call__方法,这里的cls就是<__main__.Foo object at 0x001B59F0> Foo类
        obj = cls.__new__(cls, *args, **kwargs)  ##Foo的__new__方法
        if cls == Foo1:
            obj.__init__(Foo())
        elif cls == Foo2:
            obj.__init__(Foo1())
        return obj
class Foo(metaclass=MyType):
    def __init__(self, args):
        print('============')
        self.name = args
    def f(self):
        print(self.name)
class Foo1(metaclass=MyType):
    def __init__(self, args):
        print('============')
        self.name = args
    def f1(self):
        print(self.name)
class Foo2(metaclass=MyType):
    def __init__(self, args):
        print('============')
        self.name = args
    def f2(self):
        print(self.name)
obj = Foo2()
obj.f2()
# <__main__.Foo1 object at 0x002DA4F0>

依赖注入案例二:

class Mapper:__mapper_relation = {}#私有化
@staticmethod#静态方法def register(cls, value):Mapper.__mapper_relation[cls] = value#私有字段,类等于值
@staticmethoddef exist(cls):   ###判断是否在里面if cls in Mapper.__mapper_relation:return Truereturn False@staticmethoddef value(cls):return Mapper.__mapper_relation[cls]class MyType(type):def __call__(cls, *args, **kwargs):  ##执行Type的__call__方法,这里的cls就是<__main__.Foo object at 0x001B59F0> Foo类obj = cls.__new__(cls, *args, **kwargs)  ##Foo的__new__方法arg_list = list(args)if Mapper.exist(cls):value = Mapper.value(cls)arg_list.append(value)obj.__init__(*arg_list, **kwargs)  ##在执行Foo的__init__的之前做什么操作return objclass Foo(metaclass=MyType):def __init__(self, name):self.name = namedef f1(self):print(self.name)class Bar(metaclass=MyType):def __init__(self, name):self.name = namedef f1(self):print(self.name)Mapper.register(Foo, '666')
Mapper.register(Bar, '999')
obj = Foo()print(obj)
print(obj.name)
b = Bar()
print(b.name)# <__main__.Foo object at 0x00583810>
# 666
# 999   

转载于:https://www.cnblogs.com/zcok168/p/10051328.html

python 抽象类、抽象方法、接口、依赖注入、SOLIP相关推荐

  1. python ioc di_PHP的依赖注入(DI) 和 控制反转(IoC)

    要想理解 PHP 依赖注入 和 控制反转 两个概念,就必须搞清楚如下的两个问题:DI -- Dependency Injection 依赖注入 IoC -- Inversion of Control ...

  2. PHP抽象函数的依赖注入,laravel 抽象类实现接口,具体类继承抽象类,使用依赖注入,如何知道接口选择的是哪个具体实现类啊?...

    接口类 namespace Interfaces; interface RepositoryInterface { public function all($columns = array('*')) ...

  3. python 抽象类和接口

    可以通过普通类实现接口,但是并没有起到规范作用,继承者可以选择实现或不实现 # 普通类定义接口 # class Animal(object): # def say(self): # pass # de ...

  4. python查漏补缺--抽象类和接口以及Overrides、函数重载

    目标: 掌握python中的抽象类和抽象接口. 封装和继承在java中用得挺多的,python中貌似用得真不多,但是为了应付考试,也是得了解. 学习内容: 抽象类,就是总结一些基本方法,每个子类必须自 ...

  5. Python injector 依赖注入框架使用

    介绍 在阅读Visual code源码时发现有若干"@IContextKeyService"的代码,@后面紧跟需要注入的服务,一开始比较疑惑,不知道该对象是如何传入MenuItem ...

  6. python ioc di_Spring介绍,IOC(控制反转),DI(依赖注入)介绍及两种注入方法

    Spring介绍,IOC(控制反转),DI(依赖注入)介绍及两种注入方法 第一中方法:在xml文件中注入: (1)开源的轻量级的应用开发框架 特点:a.简化开发:b.解耦:c.集成: 原理对象与对象之 ...

  7. java接口注入对象的意义_Java Web系列:Spring依赖注入基础

    一.Spring简介 1.Spring简化Java开发 Spring Framework是一个应用框架,框架一般是半成品,我们在框架的基础上可以不用每个项目自己实现架构.基础设施和常用功能性组件,而是 ...

  8. 从针对接口编程到依赖注入

    1.概况说明 2.猫狗大战举例 3.说明为什么要针对接口编程,优点 4.说明为什么要"依赖抽象,不要依赖具体类" 5.说明"依赖倒置"与抽象工厂模式 6.说明& ...

  9. Python中抽象类和接口的区别

    Python中的抽象类和接口有什么区别? #1楼 用更基本的方式来解释:界面有点像空的松饼盘. 它是一个包含一组没有代码的方法定义的类文件. 抽象类是相同的,但并非所有函数都需要为空. 有些人可以有代 ...

最新文章

  1. Symfony3.0 实践教程 (三) 安装与配置Symfony
  2. linux 网络传输压塑文件,萌新的Linux学习之路(十一)文件压缩传输
  3. 调用iframe中的函数
  4. 国内首本免费深度学习书籍!还有人没Get么?
  5. LeetCode 3sum 问题
  6. 20多年的朋友如兄弟,没有矛盾4个人如今都绝交了什么原因?
  7. Python编写的强大的、通用的解析器
  8. NAT端口映射到物理机
  9. 你电脑上「最引以为豪」的软件是什么?
  10. python检测屏幕亮点_Python+OpenCV检测灯光亮点的实现方法
  11. Java 大地坐标转经纬度,经纬度与WGS84坐标转换
  12. PCB叠层排布原则以及AD中如何设计叠层
  13. Ubuntu服务器用户磁盘空间quota分配
  14. 如何下载视频号的视频
  15. hdu 5510 Bazinga KMP+暴力
  16. 360浏览各模式及内核的使用说明
  17. 炉石传说 爬取全部卡牌
  18. 好色机器人的艳遇_机器人艳遇:《机器人的旅行》
  19. Kali、Ubuntu、银河、Uos、deepin、Centos7(8) 等 Linux 如何使用 蓝牙
  20. replace into使用

热门文章

  1. hdu -1251 统计难题(字典树水题)
  2. Chilkat -- python又一个强大的库
  3. Ruby之旅(16) 异常处理 rescue与ensure
  4. HGE引擎写的俄罗斯方块程序(附vc源码)[r]
  5. xshell 5连接NAT模式的虚拟机
  6. 可视化理解卷积神经网络 - 反卷积网络 - 没看懂
  7. [译] Node.js 流: 你需要知道的一切
  8. jquery插件函数传参错误
  9. hdu 1709 (母函数,有些特殊)
  10. 查看linux系统版本,内核,CPU,MEM,位数的相关命令