首先,我们必须明确的一点是:python中无接口类型,定义接口只是人为规定,在编程过程自我约束!
定义一个接口对继承类进行约束,接口里有什么方法,继承类就必须有什么方法,接口中不能任何功能代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class Interface:
def f1( self ):
class Something(Interface):
def f1( self ):
print ( 'to do something...' )
def f2( self ):
print ( 'to do other..' )
|
在其他的语言里,比如Java,继承类没有重写接口方法是会报错的,而在python里不会,就是因为python没这个类型,所以只是在我们编程过程的一个规定,以I开头的类视为接口
1
2
3
4
5
6
7
8
9
|
class IOrderRepository:
def fetch_one_by( self ,nid):
raise Exception( '子类中必须实现该方法' )
class Something(IOrderRepository):
def fet_one_by( self ,nid):
print ( '查查查数据....' )
|
抽象类,可以说是类和接口的混合体,既可以定义常规方法,也可以约束子类的方法(抽象方法)
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
|
import abc
class Foo(metaclass = abc.ABCMeta):
def f1( self ):
print ( 'f1' )
@abc .abstractmethod
def f2( self ):
class Bar(Foo):
def f2( self ):
print ( 'f2' )
def f3( self ):
print ( 'f3' )
b = Bar()
b.f1()
b.f2()
b.f3()
|
依赖注入
首先我们先看一个普通的类:
1
2
3
4
5
6
|
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__里面大做文章啦
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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对象,就用参数的形式传入到构造方法里
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
53
54
55
56
57
|
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)
|