首先,我們必須明確的一點是: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__方法
- 在call方法里調用Foo類的__new__方法(負責創建對象)
- 執行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)
