首先,我们必须明确的一点是: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())
if __name__ == '__main__':
Mapper.register(Foo, Head())
Mapper.register(Bar, Foo())
head = Mapper.get_value(Foo)
print('1111111')
print(head)
print(head.name)
print('2222222')
foo = Mapper.get_value(Bar)
print(foo)
print(foo.h.name)
print('3333333')
b = Bar()
print(b.f)
print(b.f.h.name)
# 输出
1111111
<__main__.Head object at 0x00000000023F4F98>
alex
2222222
<__main__.Foo object at 0x00000000023FF080>
alex
3333333
<__main__.Foo object at 0x00000000023FF080>
alex
网友评论