python中的接口和依赖注入
首先,我们必须明确的一点是: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__方法
- 在call方法里调用Foo类的__new__方法(负责创建对象)
- 执行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中的接口和依赖注入的更多相关文章
- ASP.NET MVC中使用Unity进行依赖注入的三种方式
在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...
- 在 mvc 4 中使用 unity 进行依赖注入
在 mvc 4 中使用 unity 进行依赖注入 关于依赖注入的概念,这里就不再叙述了,我们用 mvc 4 结合 unity,使用构造函数来进行依 赖注入.具体步骤如下: 1. 首先建立 一个 mvc ...
- 我在项目中运用 IOC(依赖注入)--实战篇
上一篇<我在项目中运用 IOC(依赖注入)--入门篇>只是简单的使用 IOC.实际项目使用 IOC 的情景复杂多了,比如说,构造函数有多个参数,有多个类继承同一个接口... Unity都有 ...
- IntelliJ IDEA中Mapper接口通过@Autowired注入报错的正确解决方式
转载请注明来源:四个空格 » IntelliJ IDEA中Mapper接口通过@Autowired注入报错的正确解决方式: 环境 ideaIU-2018.3.4.win: 错误提示: Could no ...
- python 抽象类、抽象方法、接口、依赖注入、SOLIP
1.程序设计原则:SOLIP SOLIP设计原则 1.单一责任原则(SRP) 一个对象对只应该为一个元素负责 2.开放封闭原则(OCP) 对扩展开放,修改封闭 3.里氏替换原则(LSP) 可以使用任何 ...
- 在ASP.NET MVC中使用Unity进行依赖注入的三种方式
在ASP.NET MVC4中,为了在解开Controller和Model的耦合,我们通常需要在Controller激活系统中引入IoC,用于处理用户请求的 Controller,让Controller ...
- 细数Javascript技术栈中的四种依赖注入
作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道 ...
- AngularJS学习--- AngularJS中XHR(AJAX)和依赖注入(DI) step5
前言:本文接前一篇文章,主要介绍什么是XHR,AJAX,DI,angularjs中如何使用XHR和DI. 1.切换工具目录 git checkout -f step- #切换分支 npm start ...
- laravel框架中所用到的依赖注入
用Laravel开发前前后后有2个月左右了,之前一直写Java,就像找到Java和PHP之前的共同点,用Java的某些原理去理解PHP会发现还是有很多共通之处的.Java的依赖注入已经是一个很常见的概 ...
随机推荐
- UVa 10633 - Rare Easy Problem
题目:给定一个数N.去掉末尾的数变成M.如今已知N-M,确定N. 分析:数论.简单题. 设N = 10*a + b { 当中0 ≤ b ≤ 9 }.则M = a: N - M = N - a = 9* ...
- asp.net mvc清空指定cookies
HttpCookie hc = Request.Cookies["user"]; hc.Expires = DateTime.Now.AddDays( ...
- php纯原生实现数组二分法
代码如下 $arr = [1,3,5,7,9];//$arr = range(1,10000);var_dump(find($arr, 2)); function find(array $arr, $ ...
- js点击标签时获取当前标签属性值
document.body.onclick=function(){ var obj = document.elementFromPoint(event.clientX,event.clientY); ...
- 记录下自己常用的全框架HTML代码
纯粹记录下,没有任何意义. 也不推荐使用 <frameset rows="> <frame src=" name="topFrame" scr ...
- makefile--嵌套执行(四)
原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 在大一些的项目里面,所有源代码不会只放在同一个目录,一般各个功能模块的源代码都是分开的,各自放在 ...
- EF的代码优先设计
CodeFirst 用中文说是代码优先,此技术可以让我们先写代码,然后由Entity Framework根据我们的代码建立数据库 接下来用学生这个例子来演示,有学生表,课程表,和成绩表三张表 首先是M ...
- raw_input()
raw_input() 用于接收标准输入,并把标准输入当成字符串类型来处理,只能在 Python2 中使用,Python3 中没有这个函数 #!/usr/bin/env python #-*- cod ...
- 通过Nagios监控weblogic服务
1.前言 前段时间搭建了一套Nagios监控服务,心血来潮想自己写一个脚本,拓展Nagios插件来监控公司的weblogic服务. 环境:weblogic10.3.3.0 . CentOS6 ...
- cocos2d-x游戏引擎核心之二——内存管理
(一) cocos2d-x 内存管理 cocos2d里面管理内存采用了引用计数的方式,具体来说就是CCObject里面有个成员变量m_uReference(计数); 1, m_uReference的变 ...