python之接口
阿新 • • 發佈:2018-01-17
foo keyword ex18 接口 interface 註入 col word pytho
首先,我們必須明確的一點是: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‘ )
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)
|
python之接口