python之接口


首先,我們必須明確的一點是: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' )
 
=  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__方法

  1. 在call方法里調用Foo類的__new__方法(負責創建對象)

  2. 執行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'
 
=  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())
 
 
=  Bar()
print (b.f)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM