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)

 

posted @ 2016-10-08 11:35  财经知识狂魔  阅读(15500)  评论(0编辑  收藏  举报