1. 程式人生 > >python之接口

python之接口

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__方法

  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‘ 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之接口