python依赖注入
2019-11-08
组合
组合就是多个类,或者若干类联合起来完成一个任务
为了降低代码的耦合度,我们一般不会在一个类里实例化另外一个类,都是将一个类在外面实例化后传参到另外一个来
这样就带来了一个问题,如果有很多类相互继承,我们就需要在外面实例化很多类
最好能动态实例化类并传参(依赖注入)
class mysql:
def __init__(self,host):
self.host = host
def connect(self):
print("连接数据库{host}".format(host=self.host))
class operator:
def __init__(self,db):
self.db = db
def query(self,user):
self.db.connect()
print("用户{user}查询成功!".format(user=user))
db = mysql('127.0.0.1')
op = operator(db)
op.query('admin')
通过type创建类
类由Type创建,当实例化一个类时,先执行Type的__call__方法
在__call__方法里执行mysql类的__new__方法
在__call__方法里执行mysql类的__init__方法
class mysql:
def __init__(self,host):
self.host = host
def connect(self):
print("连接数据库{host}".format(host=self.host))
自定义type类
class MyType(type):
print('执行__call__')
def __call__(cls, *args, **kwargs):
print('执行__new__')
obj = cls.__new__(cls,*args,**kwargs)
print('执行__init__')
obj.__init__('127.0.0.1')
return obj
class mysql(metaclass=MyType):
def __init__(self,host):
self.host = host
def connect(self):
print('连接数据库{host}'.format(host=self.host))
db = mysql('127.0.0.1')
db.connect()
依赖关系注入
依赖关系注入,就是将类与类之间的依赖关系,通过创建类时的__call__方法,在执行__init__方法之前,被注入到__init__方法里
register()第一个参数依赖关系key,第二个参数依赖关系value
如果一个类需要继承另外一个类。只要实例化父类,注入到子类的__init__方法里,这样就完成了继承
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 value(cls):
return Mapper.__mapper_relation[cls]
class MyType(type):
# 自定义type类
def __call__(cls, *args, **kwargs):
obj = cls.__new__(cls,*args,**kwargs)
arg_list = list(args)
if Mapper.exist(cls):
value = Mapper.value(cls)
arg_list.append(value)
obj.__init__(*arg_list, **kwargs)
return obj
class mysql(metaclass=MyType):
# 继承type类MyType,此类就会由MyType类创建
def __init__(self,host):
self.host = host
def connect(self):
print("连接数据库{host}".format(host=self.host))
class operator(metaclass=MyType):
def __init__(self,db):
self.db = db
def query(self,user):
self.db.connect()
print("用户{user}查询成功".format(user=user))
Mapper.register(mysql,'172.16.1.1')
Mapper.register(operator,mysql())
obj = operator()
obj.query('admin')