python中的接口和依賴注入


  首先,我們必須明確的一點是:python里無接口類型,定義接口只是一個人為規定,在編程過程自我約束

  • python的類是可以寫任意個方法的

  • 定義一個接口對繼承類進行約束,接口里有什么方法,繼承類就必須有什么方法,接口中不能任何功能代碼

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開頭的類視為接口

class IOrderRepository:

    def fetch_one_by(self,nid):
        raise Exception('子類中必須實現該方法')

class Something(IOrderRepository):

    def fet_one_by(self,nid):
        print('查查查數據....')

 

抽象類,抽象方法

  • 抽象類,可以說是類和接口的混合體,既可以定義常規方法,也可以約束子類的方法(抽象方法)

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()

 

依賴注入

首先我們先看一個普通的類:

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__里面大做文章啦

 

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對象,就用參數的形式傳入到構造方法里

 

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)

 


免責聲明!

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



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