首先,我們必須明確的一點是:python中無接口類型,定義接口只是人為規定,在編程過程自我約束!
定義一個接口對繼承類進行約束,接口里有什么方法,繼承類就必須有什么方法,接口中不能任何功能代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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開頭的類視為接口
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
):
'''
打印f2
'''
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)
|