深入理解Python中的依赖注入

一文带你深入了解Python依赖注入。

微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩

简介

依赖注入是软件工程中使用的一种设计模式,它允许在创建对象时由外部提供其依赖关系,而不是自己创建这些依赖关系。换句话说,不是从类创建自己的依赖关系,而是将依赖关系从外部注入到该类。

为什么使用依赖注入?

依赖注入的好处包括提高软件设计的灵活性和模块化,改善可测试性,以及减少组件之间的耦合。通过将对象与它们的依赖关系解耦,可以更容易地进行更改而不影响系统的其他部分。

例如,假设有一个依赖于数据库连接的类。如果在该类中创建数据库连接,就在该类和数据库之间建立了一个紧密的耦合。这意味着对数据库连接的任何更改都需要对类进行修改,这使得代码的灵活性降低,更难维护。

通过依赖注入,可以从外部将数据库连接传递给类,使代码更加模块化,更容易测试。这也允许用不同的实现来替换数据库连接,比如与不同的数据库或外部API进行交互,而不需要修改类本身。

用Python实现依赖注入

Python是一种流行的编程语言,支持几种实现依赖注入的方法。本文将使用构造函数注入来演示这一概念。

构造函数注入包括通过构造函数将依赖关系传递给一个类。这允许该类将依赖关系存储为实例变量,使它们对其方法可用。

创建一个例子来演示它是如何工作的。将从定义一个依赖于UserRepository接口的UserService类开始:

class UserService:def __init__(self, user_repository):self.user_repository = user_repositorydef get_user(self, user_id):return self.user_repository.get_user(user_id)

在此示例中,UserService类在其构造函数中把UserRepository对象作为一个参数。然后它将UserRepository对象存储为一个实例变量,并在其get_user方法中使用它。

可以通过给UserRepository添加一个get_user方法来定义它的接口:

class UserRepository:def get_user(self, user_id):raise NotImplementedError

这创建了一个简单的接口,UserRepository类的任何实现都必须实现。在这种情况下将创建一个UserRepository类的实现,叫做InMemoryUserRepository,它将用户数据存储在内存中:

class InMemoryUserRepository(UserRepository):def __init__(self):self.users = {1: {"id": 1, "name": "Alice"},2: {"id": 2, "name": "Bob"},3: {"id": 3, "name": "Charlie"},}def get_user(self, user_id):return self.users.get(user_id, None)

InMemoryUserRepository类中,定义了一个包含用户数据的字典,并实现了get_user方法,通过ID检索用户。

最后,在主函数中,创建了一个InMemoryUserRepository的实例,并将其传递给UserService的构造函数。然后在UserService实例上调用get_user方法,通过他们的ID检索用户:

if __name__ == "__main__":user_repository = InMemoryUserRepository()user_service = UserService(user_repository)user = user_service.get_user(1)

在此示例中,创建一个InMemoryUserRepository的实例,它实现了UserRepository接口。然后创建一个UserService的实例,将InMemoryUserRepository实例作为参数传给它的构造函数。最后,在UserService实例上调用get_user方法,通过ID检索一个用户。

通过使用构造函数注入,可以很容易地将UserRepository的实现换成不同的实现,比如与数据库或外部API交互的实现,而不需要修改UserService类本身。这使得代码更灵活,更容易维护。

如下所示是完整的InMemoryUserRepository.py文件:

from UserRepository import UserRepository
from UserService import UserServiceclass InMemoryUserRepository(UserRepository):def __init__(self):self.users = {1: {"id": 1, "name": "Alice"},2: {"id": 2, "name": "Bob"},3: {"id": 3, "name": "Charlie"},}def get_user(self, user_id):return self.users.get(user_id, None)if __name__ == "__main__":user_repository = InMemoryUserRepository()user_service = UserService(user_repository)user = user_service.get_user(1)print(user.get("name"))

接下来的例子展示了如何用DatabaseUserRepository的实现来替换InMemoryUserRepository的实现:

import os
import sqlite3
from UserRepository import UserRepository
from UserService import UserServiceclass DatabaseUserRepository(UserRepository):def __init__(self, db_path):self.db_path = db_pathdef get_user(self, user_id):with sqlite3.connect(self.db_path) as conn:cursor = conn.cursor()cursor.execute("SELECT id, name FROM users WHERE id=?", (user_id,))row = cursor.fetchone()if row is None:return Nonereturn {"id": row[0], "name": row[1]}if __name__ == "__main__":# 用`DatabaseUserRepository`来替换`InMemoryUserRepository`db_dir = "test"os.makedirs(db_dir, exist_ok=True)db_path = os.path.join(db_dir, "test.db")with sqlite3.connect(db_path) as conn:cursor = conn.cursor()cursor.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")cursor.execute('INSERT INTO users (id, name) VALUES (1, "Alice")')cursor.execute('INSERT INTO users (id, name) VALUES (2, "Bob")')cursor.execute('INSERT INTO users (id, name) VALUES (3, "Charlie")')user_repository = DatabaseUserRepository(db_path)user_service = UserService(user_repository)user = user_service.get_user(1)print(user["name"])

在此示例中,os模块被用来在当前工作目录中创建一个名为“test”的新目录(如果它还不存在的话),并且通过连接目录路径和文件名“test.db”来创建SQLite数据库文件的路径。

然后建立与数据库的连接,创建一个用户表,并将一些测试数据插入该表中。

最后,创建一个DatabaseUserRepository类的实例,db_path参数设置为测试数据库文件的路径,这个实例被用来创建UserService类的实例。然后调用UserService类的get_user()方法,参数为1,ID为1的用户的名字被打印到控制台。

本文的所有代码都可以在Github上找到:https://github.com/PythonCodeNemesis/Python_Dependancy_Injector_Demo

总结

依赖注入是一种强大的设计模式,可以帮助使软件更加模块化、更加灵活、更加容易测试。Python提供了几种实现依赖注入的方法,包括构造函数注入,在本文中演示了这种方法。

通过使用依赖注入,可以创建与依赖关系解耦的类,使修改和维护代码更加容易。这也可以提高软件的整体质量,并使其更有弹性地应对长期的变化。

推荐书单

《Python从入门到精通(微课精编版)》

《Python从入门到精通(微课精编版)》使用通俗易懂的语言、丰富的案例,详细介绍了Python语言的编程知识和应用技巧。全书共24章,内容包括Python开发环境、变量和数据类型、表达式、程序结构、序列、字典和集合、字符串、正则表达式、函数、类、模块、异常处理和程序调试、进程和线程、文件操作、数据库操作、图形界面编程、网络编程、Web编程、网络爬虫、数据处理等,还详细介绍了多个综合实战项目。其中,第24章为扩展项目在线开发,是一章纯线上内容。全书结构完整,知识点与示例相结合,并配有案例实战,可操作性强,示例源代码大都给出详细注释,读者可轻松学习,快速上手。本书采用O2O教学模式,线下与线上协同,以纸质内容为基础,同时拓展更多超值的线上内容,读者使用手机微信扫一扫即可快速阅读,拓展知识,开阔视野,获取超额实战体验。

《Python从入门到精通(微课精编版)(软件开发视频大讲堂)》(前沿科技)【摘要 书评 试读】- 京东图书京东JD.COM图书频道为您提供《Python从入门到精通(微课精编版)(软件开发视频大讲堂)》在线选购,本书作者:,出版社:清华大学出版社。买图书,到京东。网购图书,享受最低优惠折扣!icon-default.png?t=N5K3https://item.jd.com/13524355.html

精彩回顾

《用好这9个技巧,让你的Python代码“飞”起来》

《领略数学之美,使用Python创建分形图案》

《使用Python进行自动化录屏》

《轻松完成异步任务,一文搞懂Python Celery》

《ChatGPT插件使用攻略,解锁互联网新体验》

《使用Python轻松创建Flask API后台任务》

《使用ChatGPT API创建Python文档,竟然如此简单》

微信搜索关注《Python学研大本营》,加入读者群

访问【IT今日热榜】,发现每日技术热点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38453.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

独立开发变现周刊(第84期):一个地理位置API服务,月收入1.5万美元

分享独立开发、产品变现相关内容,每周五发布。 (合集:https://ezindie.com/weekly ) 目录 1、tiny.host: 简单部署你的web项目2、Verif Tools: 一个在线虚拟身份信息生成器3、screen.studio: 一个桌面端的录屏编辑工具4、一个地理位置API服务&#xff0c…

李彦宏:十年后不会写提示词或被淘汰;GitHub发布Copilot X,动动嘴就能生成代码;Vite 4.2 发布|极客头条...

「极客头条」—— 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews) 一分钟速览新闻点&#…

22个提升生产力的工具推荐,稳了

子曰:工欲善其事,必先利其器。 本文给大家推荐22个提高生产力的工具,总有一款符合你的需求。😄😄😄 提高生产效率工具推荐 滴答清单/Todoist文件检索利器:Everything文件管理软件-Allen Explor…

百度抢先发布中国版ChatGPT——文心一言,现已开通测试申请

3月16日,百度抢先其他国内科技巨头一步,率先发布被誉为中国版ChatGPT的“文心一言”。 即日起,百度也通过“百度智能云”官网正式开发“文心一言”的预约,申请云服务测试。 但是,目前百度智能云只面向企业级客户开放文…

chatgpt赋能python:Python录制屏幕:如何用Python录制屏幕

Python录制屏幕:如何用Python录制屏幕 如果你曾经想过如何在电脑上录制自己的屏幕以制作教学视频或演示产品,那么你需要了解一些关于Python录制屏幕的知识。Python是一门强大的动态编程语言,因其易于学习、连接数据库和编写简洁的代码&#…

chatgpt赋能python:Python中常见的Module报错及解决方法

Python中常见的Module报错及解决方法 在Python编程过程中,经常会使用各种第三方库和模块,以提高代码的效率和可读性。然而,在使用这些模块时,我们有时会遭遇各种各样的错误和异常。本文将介绍Python中常见的Module报错现象及其解…

chatgpt赋能Python-pythonimport报错

Python中Import报错的处理方法 Python是一款非常流行的编程语言,也是众多开发者选择的首选。在代码中,我们通常会使用import语句来引入其他模块,但在实际开发过程中,我们有时会遇到ImportError:No module named XXX等…

chatgpt赋能Python-pythonnumpy报错

Python中Numpy出现报错的解决方法 介绍 Numpy是Python中常用的数学计算库,其支持高效的数组处理和运算,是很多数据科学工程师必备的编程工具之一。由于其强大的功能和灵活性,Numpy在各行各业都有广泛的应用。但有时候在使用Numpy时可能会出…

Open Ai 常见接口参数说明以及常见报错总结

📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言&#x1f4d…

chatgpt赋能python:Python打开文件遇到的常见报错类型

Python打开文件遇到的常见报错类型 Python作为一种高级编程语言,在开发过程中经常需要读取或写入文件。然而,在实际操作中,我们经常会遇到一些FileNotFoundError、PermissionError等错误类型。在本文中,我将介绍常见的Python打开…

记者亲测GPT-4实际能力 围观10种职业“受虐”现场

出品|网易科技《智见焦点》 作者|赵芙瑶 编辑|丁广胜 作为OpenAI公司开发的一种生成式人工智能工具,有关学者以“阿拉丁神灯”和“潘多拉魔盒”来比喻ChatGPT所隐藏的潜能和可能带来的风险。自其发布以来,有关ChatGPT是…

文本聚类与摘要,让AI帮你做个总结

你好,我是徐文浩。 过去的十多讲里,我为你介绍了各种利用大语言模型的方法和技巧。特别是在过去两讲里,我们也尝试更加深入地利用开源代码帮我们完成一些工作。通过llama-index这样的开源库,我们能够将自己的数据和大语言模型连接…

物以类聚人以群分,通过GensimLda文本聚类构建人工智能个性化推荐系统(Python3.10)

众所周知,个性化推荐系统能够根据用户的兴趣、偏好等信息向用户推荐相关内容,使得用户更感兴趣,从而提升用户体验,提高用户粘度,之前我们曾经使用协同过滤算法构建过个性化推荐系统,但基于显式反馈的算法就…

01表盘控件-01汽车仪表盘-gaugecar

一、运行效果 二、功能特点 可设置范围值,支持负数值。可设置精确度,最大支持小数点后3位。可设置大刻度数量,小刻度数量。可设置开始旋转角度,结束旋转角度。可设置外圆背景、内圆背景、饼圆三种颜色、刻度尺颜色、文字颜色。自…

01表盘控件-17飞机仪表盘-gaugeplane

一、运行效果 二、功能特点 可设置外边框渐变颜色。可设置里边框渐变颜色。可设置主背景颜色、遮罩层颜色、刻度尺颜色。可设置线条颜色、文字颜色、指针颜色、遥感句柄颜色。可设置旋转角度。可设置滚动值。三、公共接口 public Q_SLOTS://设置外边框渐变颜色void setBorderO…

浅谈大数据之足球盘口赔率水位分析的思路与神准预测技巧(一)

足球运动是当今世界上开展最广、影响最大、最具魅力、拥有球迷数最多的体育项目之一,尤其是欧洲足球,每年赛事除了五大联赛(英超、西甲、德甲、法甲、意甲)之外,还会有欧冠(欧洲冠军联赛)&#…

chatgpt赋能python:Python数据分析

Python数据分析 什么是Python数据分析 Python是一种简单易学、功能强大的编程语言,它是数据科学中最常用的开发语言之一。数据分析是Python的主要用途之一。Python的开源性、易于使用和拥有强大的数据科学库使它成为学术和商业环境下最受欢迎的数据分析工具之一。…

Telegram-This phone number is banned.手机号被禁止解决方法

问题: 解决方法:1.点击提示框左下角的HELP弹出如下提示框: 2.在手机上下载一个QQ邮箱,然后点击左下角“通过邮件发送”,会出现下图: 会自动生成申诉的邮件,只需点击发送邮件即可。大约要等待…

德国法庭禁止Whatsapp,Facebook和Instagram

Whatsapp,Instagram和Facebook这些智能手机应用程序侵犯了加拿大公司黑莓(Blackberry)所拥有的专利,因此慕尼黑地方法院因作出裁决,Facebook可能将禁止在德国提供这些应用程序。 加拿大软件公司黑莓(Blackberry)在针对…

一觉睡醒,ChatGPT竟然被淘汰了?

来源:机器之心 注:本标题是 AutoGPT 建议我修改的 OpenAI 的 Andrej Karpathy 都大力宣传,认为 AutoGPT 是 prompt 工程的下一个前沿。 近日,AI 界貌似出现了一种新的趋势:自主人工智能。 这不是空穴来风&#xff0c…