Python 在编程领域已经存在了二十多年,多年来,该语言经历了许多改进,社区不断壮大,以及大量生产就绪且支持良好的库。但是 Python 准备在企业应用开发领域中产生一个凹痕,它长期以来一直被 C++、java 和.net 之类的企业所统治,所谓的企业级语言 ToeT1?
在本章中,我们将看到 Python 多年来是如何发展的,以及它是如何准备成为企业应用开发领域的一个重要竞争对手的。
本章将涵盖以下主题:
- Python 的最新发展使其在企业应用开发中得以增长
- Python 大放异彩的特殊用例
- 企业软件与通用软件的区别
- 开发企业应用的要求
可以通过运行以下命令克隆代码示例:
git clone https://github.com/PacktPublishing/Hands-On-Enterprise-Application-Development-with-Python
运行代码的说明可以在各个章节目录的README
文件下找到。
该代码已经过测试,可以在运行 Fedora28 和 Python 版本 3.6.5 的系统上运行,但它应该能够在运行 Python 3.6.5 的任何系统上运行。
Python 是一种动态类型的解释语言,最初非常适合于编写枯燥重复的日常任务的脚本。但随着时间的推移,该语言获得了许多新功能和社区的大力支持,这推动了它的发展,使其成为一种非常适合执行任务的语言,这些任务包括非常简单的应用,如网页抓取,分析大量数据,以训练用 Python 编写的机器学习模型。让我们看看这些年来发生的一些重大变化,看看 Python,Python 3 的最新版本带来了什么。
Python 作为一种语言已经发展了很多年,但尽管如此,用 Python 1.0 编写的程序仍然能够在 Python 2.7 中运行,Python 2.7 是在 Python 1.0 发布 19 年后发布的版本。
虽然对 Python 应用的开发人员来说这是一个很大的好处,但是这种语言的向后兼容性也是语言规范重大改进的增长和发展中的一个主要障碍,因为如果对语言规范进行重大更改,大量较旧的代码库将被破坏。
随着 Python3 的发布,这种向后兼容性的链条被打破了。版本 3 中的语言放弃了对早期版本中编写的程序的支持。。。
在 Python2 时代,文本数据类型str
用于支持 ASCII 数据,而对于 Unicode 数据,该语言提供了unicode
数据类型。当有人想要处理特定的编码时,他们会获取一个字符串并将其编码到所需的编码方案中。
此外,该语言固有地支持字符串类型到unicode
类型的隐式转换。这显示在以下代码段中:
str1 = 'Hello'
type(str1) # type(str1) => 'str'
str2 = u'World'
type(str2) # type(str2) => 'unicode'
str3 = str1 + str2
type(str3) # type(str3) => 'unicode'
这通常是可行的,因为在这里,Python 会使用默认编码将字节字符串str1
隐式解码为 Unicode,然后执行串联。这里需要注意的一点是,如果这个str1
字符串包含任何非 ASCII 字符,那么这种连接在 Python 中就会失败,并引发UnicodeDecodeError
。
随着 Python3 的到来,处理文本的数据类型发生了变化。现在,用于存储文本的默认数据类型str
支持 Unicode。因此,Python 3 还引入了一种二进制数据类型,称为bytes
,可用于存储二进制数据。这两种类型str
和bytes
是不兼容的,它们之间不会发生隐式转换,任何尝试都会导致TypeError
,如下代码所示:
str1 = 'I am a unicode string'
type(str1) # type(str1) => 'str'
str2 = b"And I can't be concatenated to a byte string"
type(str2) # type(str2) => 'bytes'
str3 = str1 + str2
-----------------------------------------------------------
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
正如我们所看到的,尝试将unicode
类型字符串与byte
类型字符串连接失败,因为TypeError
。虽然不可能将string
隐式转换为byte
或byte
隐式转换为string
,但我们确实有方法可以将string
编码为bytes
类型,并将bytes
类型解码为string
。请看以下代码:
str1 = ' ₹100 '
str1.encode('utf-8')
# b'\xe2\x82\xb9100'
b'\xe2\x82\xb9100'.decode('utf-8')
# '₹100'
字符串类型和二进制类型之间的这种明显区别,以及对隐式转换的限制,使得代码更健壮,错误更少。但这些更改也意味着,由于向后不兼容,在 Python2 中用于处理 Unicode 的任何代码都需要在 Python3 中重写。
Here, you should focus on the encoding and decoding format used to convert string
to bytes
and vice versa. Choosing a different formatting for encoding and decoding can result in the loss of important information, and can result in corrupt data.
Python 是一种动态类型化语言,因此,在为变量赋值后,解释器将在运行时对变量的类型进行评估,如以下代码所示:
a = 10type(a) # type(a) => 'int'a = "Joe" type(a) # type(a) => 'str'
虽然在编写代码库易于跟踪的小程序时,变量类型的动态解释非常方便,但在使用非常大的代码库时,语言的功能也可能成为一个大问题,这会产生很多模块,而且,跟踪特定变量的类型可能会成为一项挑战,与使用不兼容类型相关的愚蠢错误很容易发生。请看以下代码:。。。
开发每种语言都是为了解决开发人员在为特定领域构建软件时所面临的特定类型的问题。Python 是一种动态类型化的解释语言,它也有一组优秀的用例。
这些用例涉及重复和枯燥任务的自动化、应用的快速原型化,以及专注于实现特定目标的小型应用,例如安装软件、设置开发环境、执行清理等。
但就这些吗?Python 只适合做小任务吗?答案是否定的。Python 作为一种语言,功能强大得多,可以轻松完成大量日益复杂的任务,例如运行一个可扩展的网站,在很短的时间内处理数百万用户使用它,处理大量传入文件,或者为图像识别系统训练机器学习模型。
我们正在谈论使用 Python 实现越来越复杂的任务,但是 Python 与传统的编译时语言相比不是慢的,例如 C++、java 和.NET?这完全取决于人们想要使用 Python 的上下文。如果您的目标是在处理能力有限的嵌入式设备上运行 Python 程序,那么是的,Python 可能不够,因为它的解释器在处理环境中会有额外的负载。但是,如果您计划使用 Python 在配置合理的现代硬件上运行 web 应用,那么在使用 Python 时可能永远不会遇到任何减速。相反,在使用它时,您可能会觉得更有效率,因为它的语法非常简单,并且易于执行操作,而无需编写数百行代码来完成简单的任务。
那么,让我们看看 Python 在企业环境中的表现。
企业 IT 非常复杂,需要为企业构建的应用与为普通消费者构建的应用有很大不同。在为企业用户开发应用之前,需要记住几个因素。让我们看看什么使得企业 IT 应用不同于常规的消费者提供,如下面的列表所示:
- 面向业务:与为解决个人用户问题而构建的应用不同,企业应用是为满足组织的特定需求而构建的。这要求应用符合组织的业务实践、ir 规则及其使用的工作流。
- 稳健性。。。
Python 以多种形式出现在企业生态系统中;无论是枯燥和重复性任务的自动化、用作产品两层之间的粘合剂,还是用于为大型服务器后端构建快速易用的客户机,该语言在各种用例中的应用越来越多。但是,是什么让 Python 为大型企业应用的开发做好了准备?让我们来看一看:
-
构建快速原型的能力:Python 的语法非常简单,很多事情都可以用很少的代码行来实现。这允许开发人员快速开发和迭代应用的原型。除此之外,这些原型并不总是需要扔掉,如果开发计划得当,它们可以作为构建最终应用的良好基础。
With the ability to quickly prototype an application, an enterprise software developer can see exactly how the requirements align in the application and how the application is performing. With this information, the stakeholders of the application can more accurately define the path for the application development, thereby avoiding midcycle architectural changes because something didn't work out the way it was expected to.
-
成熟的生态系统:成熟的生态系统是 Python 值得关注的特性之一。Python 中外部库的数量一直在快速增长。对于需要在应用中实现的大多数任务,例如双因素身份验证、测试代码、运行生产 web 服务器、与消息总线集成等,您可以很容易地找到具有相当不错的支持的库。
这证明是非常有帮助的,因为它减少了代码重复的数量,并提高了组件的可重用性。在
pip
等工具的帮助下,将所需的库添加到项目中非常容易,并且在virtualenv
等工具的支持下,您可以轻松地在同一个系统上隔离许多不同的项目,而不会造成依赖关系混乱。例如,如果有人想要构建一个简单的 web 应用,他们可能只需要使用 Flask,这是一个用于开发 web 应用的微框架,然后继续开发 web 应用,而不必担心处理套接字、操作套接字上的数据的潜在复杂性。他们只需要几行代码就可以启动并运行一个简单的应用,如下代码所示:
from flask import Flask
app = Flask(__name__)
@app.route('/', methods=["GET"])
def hello():
return "Hello, this is a simple Flask application"
if name == '__main__':
app.run(host='127.0.0.1', port=5000)
现在,只要有人调用前面的脚本,就会有一个flask
HTTP 应用启动并运行。这里要做的就是启动浏览器并导航到http://localhost:5000
。然后,我们将看到 Flask 毫不费力地为 web 应用提供服务。所有这些都是在不到 10 行代码中实现的。
有了大量的外部库为许多任务提供支持,企业开发人员就可以轻松地支持应用中的新功能,而无需从头开始编写所有内容,从而减少可能的 bug 和非标准化接口潜入应用的机会
- **社区支持:**Python 语言不属于任何特定的公司实体,完全由决定标准未来的巨大社区支持提供支持。这确保了该语言将在相当长的一段时间内继续受到支持,并且不会很快过时。这对组织来说非常重要,因为他们需要对运行的应用提供长期支持。
考虑到 Python 前面的所有好处,如果决策是以一种精心计划的方式做出的,那么开发人员在使用该语言时的生产率将得到提高,同时也会降低软件的总体拥有成本。这些决策涉及应用体系结构的布局方式以及内部使用或开发哪些外部库。因此,是的,Python 现在确实可以在企业应用开发的主流世界中使用了。
随着本书各章的深入,我们需要一些方法来实现我们所学到的东西。
假设您在一家名为欧米茄公司的公司工作,该公司是向公司和个人销售软件产品的市场领导者。欧米茄公司需要一个系统,通过它可以跟踪其产品中的缺陷。经过大量的头脑风暴后,他们启动了一个名为 BugZot 的项目,该项目将成为他们跟踪产品中缺陷的工具。
让我们来看看欧米茄公司希望通过 BugZot 项目实现什么:
- 用户报告产品缺陷的能力:用户,无论是内部用户还是外部用户,都应该能够针对特定产品提交缺陷。。。
在开始开发企业应用之前收集软件需求可能是一项繁琐的任务,如果不能充分收集,可能会产生严重的后果,例如由于在应用开发周期的后期识别需求而导致的延迟而增加成本。缺少改善业务流程工作流的重要功能的应用将导致用户在最坏的情况下停止使用该应用。
需求收集过程复杂而乏味,在组织中可能需要几个月才能完成。涵盖过程中涉及的所有步骤超出了本书的范围。本节试图简要描述收集软件需求过程中的一些重要步骤。
对于组织内部的应用,可能有不同的用户,他们是利益相关者,可以定义应用的需求。这些用户可大致分为两类:
-
工作人员:这些用户通常使用应用来完成某一组任务。他们并不关心应用提供的所有功能,而是关注应用与各自工作流的匹配程度。这些用户可以提供特定于他们工作内容的需求,但可能无法提供关于他们将来可能需要什么或其他团队可能需要什么的想法。
-
管理层:管理层由人组成。。。
一旦调查了用户希望在应用中拥有什么,下一步就是对这些需求进行分类。大体上,要求可分为两部分:
-
功能需求:这些需求定义了应用的特性和功能。例如,BugZot 具有以下功能需求:
- 提供内部和外部用户归档 bug 的功能
- 提供对角色和权限的支持
- 提供处理文件上载的功能
- 与电子邮件系统集成,在 bug 改变状态时发送电子邮件,等等
-
非功能性需求:这些需求集不影响软件的功能,而是基于功能性需求的隐式或显式特征。例如,在 BugZot 中,以下可能被定义为一些非功能性需求:
-
应用应提供针对常见 web 攻击向量(如 XSS 和 CSRF)的安全性
-
应用的运营成本不得超过总预算的N%
-
应用应该能够生成备份,以防崩溃后需要恢复
一旦需求被识别并分类为功能性需求和非功能性需求,就需要根据它们在应用中的重要性对它们进行优先级排序。如果不执行这种优先级划分,将导致开发成本增加、截止日期延迟,并降低组织的生产率。大体上,我们可以将需求分为以下几类:
- 必须有:这些要求对应用的成功至关重要,并且在应用发货时必须存在。
- 应该有:这些需求将增强应用的功能,但需要进一步讨论它们是否。。。
一旦对需求进行了识别、分组和优先级排序,就会生成一个称为软件需求规范的文档。本文档描述了需要开发的软件的预期用途、要求和性质。
软件需求说明书(SRS将描述以下信息:
- 申请的预期目的
- 文档中使用的特定于组织业务流程的约定
- 应用的特性
- 将使用应用的用户类
- 应用将在其中运行的环境
- 应用的功能性和非功能性需求
生成 SRS 后,将其发送以供审查和进一步协商。一旦成功完成,应用将进入设计阶段,在此阶段将设计应用模型。
在本章中,我们简要介绍了不断变化的编程环境,并探讨了 Python 生态系统多年来的变化。鉴于 Python 允许快速原型化,并且拥有大量支持良好的库和开放社区,我们了解了 Python 如何迅速崛起,成为企业中开发大规模应用的主要选择,这些企业需要长期支持并易于与现有系统集成
然后,我们继续介绍演示应用 BugZot,我们将在本书的整个过程中构建它,并定义应用所需的功能。
本章的最后一节介绍了……的需求收集过程。。。
-
在 Python3 中,是否可以对
str
类型和byte
类型执行连接等操作? -
Python3 中是否引入了类型暗示支持?
-
除了功能性和非功能性需求之外,是否还有其他类型的需求也需要记录到软件需求规范中?
-
在哪些主要类别中可以进行需求优先级排序?
-
一旦生成了软件需求规范文档,接下来要采取什么步骤
如果您想在进入企业应用开发领域之前再次学习 Python 编程的基础知识,Packt 有一本非常好的书,您可以参考。您可以通过以下链接获得: