普通的例子

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

  [py]
1
2
3
4
5
6
class Foo: def __init__(self): self.name = 'ryo' def f1(self): print(self.name)

基础知识

首先要明确的是,在python里,一切事物皆为对象

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

创建类的执行流程

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

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

  3. 在call方法里调用Foo类的 __new__ 方法(负责创建对象)

  4. 执行Foo类的 __init__ 方法(初始化)

在 call 中大做文章

  • IOC.py
  [py]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
''' desc: 依赖注入测试案例 author: binbin.hou ''' class MyType(type): def __call__(cls,*args,**kwargs): obj = cls.__new__(cls,*args,**kwargs) print('call() method called!') obj.__init__(*args,**kwargs) return obj class Foo(metaclass=MyType): def __init__(self): self.name = 'ryo' ''' 测试部分代码 ''' f = Foo() print(f.name)
  • 测试日志
  [plaintext]
1
2
3
λ python IOC.py call() method called! ryo

和组合结合

组合的概念

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

在 java spring 框架中,组合是非常常见的一种方式。

一个 service 由其他的 service/mapper 组合而成。做到高内聚,低耦合。

案例

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

  [py]
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
40
41
42
43
44
45
46
47
48
49
50
51
52
''' desc: 依赖注入组合测试案例 author: binbin.hou ''' class Mapping: # 映射集合 mapping_col = {} @staticmethod def register(cls,value): Mapping.mapping_col[cls]=value @staticmethod def getCls(cls): return Mapping.mapping_col[cls] class MyType(type): def __call__(cls,*args,**kwargs): obj = cls.__new__(cls,*args,**kwargs) print('call() method called!') args_list = list(args) args_list.append(Mapping.getCls(cls)) obj.__init__(*args_list,**kwargs) return obj class Foo(): def __init__(self): self.name = 'ryo' def f(self): print('This name: ', self.name) class Bar(metaclass=MyType): def __init__(self,obj): self.f = obj.f def f2(self): self.f() ''' 测试部分代码 ''' # 注册 Mapping.register(Bar,Foo()) # 测试 b = Bar() b.f2()
  • 测试日志信息
  [plaintext]
1
2
3
$ python IOC_combine.py call() method called! This name: ryo

常见报错

问题

  [plaintext]
1
TabError: inconsistent use of tabs and spaces in indentation

解决方式

使用空格代替 tab 符号。

【首选项】=》【语言】=》【Python】=》【制表符设置】勾选上替换为空格。

参考资料

python中的接口和依赖注入

  • nodepad++ 的 tab 问题

https://www.cnblogs.com/cbl321/p/8074146.html