首先,我们必须明确的一点是:python里无接口类型,定义接口只是一个人为规定,在编程过程自我约束

  • python的类是可以写任意个方法的

  • 定义一个接口对继承类进行约束,接口里有什么方法,继承类就必须有什么方法,接口中不能任何功能代码

class Interface:

    def f1(self):
'''
to do something
:return:
''' class Something(Interface): def f1(self):
print('to do something...') def f2(self):
print('to do other..')

  在其他的语言里,比如Java,继承类没有重写接口方法是会报错的,而在python里不会,就是因为python没这个类型,所以只是在我们编程过程的一个规定,以I开头的类视为接口

class IOrderRepository:

    def fetch_one_by(self,nid):
raise Exception('子类中必须实现该方法') class Something(IOrderRepository): def fet_one_by(self,nid):
print('查查查数据....')

抽象类,抽象方法

  • 抽象类,可以说是类和接口的混合体,既可以定义常规方法,也可以约束子类的方法(抽象方法)

import abc

#抽象类
class Foo(metaclass=abc.ABCMeta): def f1(self):
print('f1') #抽象方法
@abc.abstractmethod
def f2(self):
'''
打印f2
''' class Bar(Foo): def f2(self):
print('f2') def f3(self):
print('f3') b = Bar()
b.f1()
b.f2()
b.f3()

依赖注入

首先我们先看一个普通的类:

class Foo:
def __init__(self):
self.name = 'alex' def f1(self):
print(self.name)
  • 首先要明确的是,在python里,一切事物皆为对象

  • 而所有的类都是对象,默认是由type创建

创建类的执行流程:

  • 遇到class关键词,执行type的__init__方法,创建Foo类这个对象

  • 遇实例化对象(obj=Foo()),执行type里的__call__方法

  1. 在call方法里调用Foo类的__new__方法(负责创建对象)
  2. 执行Foo类的__init__方法(初始化)

了解其中的原理,我们就可以在__call__里面大做文章啦

class MyType(type):

    def __call__(cls,*args,**kwargs):
obj = cls.__new__(cls,*args,**kwargs)
print('在这里面..')
print('==========================')
print('来咬我呀')
obj.__init__(*args,**kwargs)
return obj class Foo(metaclass=MyType): def __init__(self):
self.name = 'alex' f = Foo()
print(f.name)

  如果要熟练应用依赖注入,我还要弄懂一个概念,那就是组合:组合的目的就是解耦,减少依赖性,原来以某个具体的值或对象传入到内部改成以参数的形式传入

  比如:在实例Bar对象时,封装Foo对象,实例Foo对象封装Head对象,就用参数的形式传入到构造方法里

class Mapper:

    #在字典里定义依赖注入关系
__mapper_relation = {} #类直接调用注册关系
@staticmethod
def register(cls,value):
Mapper.__mapper_relation[cls] = value @staticmethod
def exist(cls):
if cls in Mapper.__mapper_relation:
return True
return False @staticmethod
def get_value(cls):
return Mapper.__mapper_relation[cls] class MyType(type):
def __call__(cls,*args,**kwargs):
obj = cls.__new__(cls,*args,**kwargs)
arg_list = list(args)
if Mapper.exist(cls):
value = Mapper.get_value(cls)
arg_list.append(value)
obj.__init__(*arg_list,**kwargs)
return obj class Head: def __init__(self):
self.name = 'alex' class Foo(metaclass=MyType): def __init__(self,h):
self.h = h def f1(self):
print(self.h) class Bar(metaclass=MyType): def __init__(self,f):
self.f = f def f2(self):
print(self.f) Mapper.register(Foo,Head())
Mapper.register(Bar,Foo()) b = Bar()
print(b.f)

python中的接口和依赖注入的更多相关文章

  1. ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...

  2. 在 mvc 4 中使用 unity 进行依赖注入

    在 mvc 4 中使用 unity 进行依赖注入 关于依赖注入的概念,这里就不再叙述了,我们用 mvc 4 结合 unity,使用构造函数来进行依 赖注入.具体步骤如下: 1. 首先建立 一个 mvc ...

  3. 我在项目中运用 IOC(依赖注入)--实战篇

    上一篇<我在项目中运用 IOC(依赖注入)--入门篇>只是简单的使用 IOC.实际项目使用 IOC 的情景复杂多了,比如说,构造函数有多个参数,有多个类继承同一个接口... Unity都有 ...

  4. IntelliJ IDEA中Mapper接口通过@Autowired注入报错的正确解决方式

    转载请注明来源:四个空格 » IntelliJ IDEA中Mapper接口通过@Autowired注入报错的正确解决方式: 环境 ideaIU-2018.3.4.win: 错误提示: Could no ...

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

    1.程序设计原则:SOLIP SOLIP设计原则 1.单一责任原则(SRP) 一个对象对只应该为一个元素负责 2.开放封闭原则(OCP) 对扩展开放,修改封闭 3.里氏替换原则(LSP) 可以使用任何 ...

  6. 在ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC4中,为了在解开Controller和Model的耦合,我们通常需要在Controller激活系统中引入IoC,用于处理用户请求的 Controller,让Controller ...

  7. 细数Javascript技术栈中的四种依赖注入

    作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道 ...

  8. AngularJS学习--- AngularJS中XHR(AJAX)和依赖注入(DI) step5

    前言:本文接前一篇文章,主要介绍什么是XHR,AJAX,DI,angularjs中如何使用XHR和DI. 1.切换工具目录 git checkout -f step- #切换分支 npm start ...

  9. laravel框架中所用到的依赖注入

    用Laravel开发前前后后有2个月左右了,之前一直写Java,就像找到Java和PHP之前的共同点,用Java的某些原理去理解PHP会发现还是有很多共通之处的.Java的依赖注入已经是一个很常见的概 ...

随机推荐

  1. CentOS运维常用管理操作命令

    自己整理的整理Linux常用运维和linux常用管理操作命令,当然不是非常详细和丰富,但是也基本上够用了吧.欢迎留言补充更多的Linux常用运维和linux常用管理操作命令.不断完善中.... 备份m ...

  2. js时间转化

    const defaultTicks = 621355968000000000; export function convertDateToTicks(date = new Date()) { ret ...

  3. optimization blocks (csapp chapter 5.1)

    p_511 编译器在没有指示下,会做‘ safe optimization',因此有些优化在没有参数的指示下是不会对代码做优化的,故在程序中应该避免某一类代码,因为它们妨碍了编译器做优化. optim ...

  4. oracle解决多表关联分组查询问题

    做了一个功能需要分组查询,同时查询A表分组查询的ID需要关联B表的数据,本来想两个表关联查询,但是报group by 语法不正确.所以做了以下修改. select count(*), cindexid ...

  5. Java 中 Map与JavaBean实体类之间的相互转化

    /** * 将一个 JavaBean 对象转化为一个  Map * @param bean 要转化的JavaBean 对象 * @return 转化出来的  Map 对象 * @throws Intr ...

  6. Tcp/ip实验准备:一个简单的定时器——boost实现

    tcp/ip实验须要在指定的时间查看结果,为了实验方便,做了一个定时器.用法是: 在命令行输入:timer 输入数字之后,计时对应秒数 输入m数字之后.计时对应分钟数(支持小数分钟数) 输入q退出. ...

  7. 超全面的JavaWeb笔记day03<JS对象&函数>

    1.js的String对象(****) 2.js的Array对象 (****) 3.js的Date对象 (****) 获取当前的月 0-11,想要得到准确的月 +1 获取星期时候,星期日是 0 4.j ...

  8. python2.0_day19_后台数据库设计思路

    from django.db import models # Create your models here. from django.contrib.auth.models import User ...

  9. osgEarth2.8加载矢量数据描边效果

    通过修改osgearth自带的agglite插件,实现矢量描边效果,可以自定义描边的颜色和宽度(单位像素) 测试文件osgearth_features.cpp #include <osg/Not ...

  10. go的临时对象池--sync.Pool

    作者:bigtom链接:https://www.jianshu.com/p/2bd41a8f2254來源:简书   一个sync.Pool对象就是一组临时对象的集合.Pool是协程安全的. Pool用 ...