Java 开发人员的 Python 基础

2025年3月17日 | 阅读19分钟

Python 是一种通用编程语言。通过了解其易用性、学习便利性以及其在机器学习数据分析和网页设计方面的应用能力,我们可以很容易地理解 Python 在过去几年中的发展。它属于哪种编程语言?Java 和 Python 之间主要区别是什么?我们可以从中获得什么?

在本教程中,我们将从 Java 的角度学习 Python。阅读本教程后,我们将能够确定 Python 是否能解决我们的问题,并认识到如何将 Python 与 Java 一起用于特定类型的问题。

Python 的起源

Python 是一种由 Guido van Rossum 创建的编程语言。他在 1989 年圣诞节期间寻找一个基于兴趣的编程项目来打发时间。那时他开始开发 Python 解释器。

Python 源自多种语言,包括 ABC、CModula-3。它是一种面向对象、命令式编程语言。

根据我们的个人喜好和我们想要的功能,可以使用完全面向对象或包含函数的过程式编程风格。本教程的下一节将讨论面向对象编程功能。

在 2021 年初,TIOBE 宣布 Python 第四次成为“年度编程语言”。根据 2021 年的 Octoverse 报告,Python 在 GitHub 上是贡献者使用量排名第二的编程语言。

Python 的哲学是什么?

很快,我们将在本教程的后续部分使用 Python。但是,首先,我们将通过研究我们可以与 Python 哲学联系起来的特性来探讨为什么彻底熟悉 Python 很重要。

Java 和 Python 的一些概念可以进行比较;但是,每种软件语言都有其独特的特性。Python 的核心哲学可以用一套 19 条基本原则来描述,这就是 Python 之禅。Python 充满了隐藏的彩蛋,其中之一就是 Python 之禅。让我们看看当我们在 Python read-eval-print loop (REPL) 中运行以下命令时会发生什么:

输出

Basic Python for Java Developers

虽然不建议对上述陈述过于当真,但其中有几条直接与我们将在下一节中探讨的特性相关。

当我们查看 Python 之禅的原则时,我们将对使用该语言的最佳方式有一个概念。

Python 代码可读性高

如果我们有 Java 背景,并且正在查看一段普通的 Python 软件,我们可能会认为我们正在查看伪代码。有几个因素可以促成这一点:

  • 缩进用于创建分组语句。这有助于缩短代码块并鼓励一致的编码风格。稍后将提供有关此问题的更多信息。
  • 一些高级内置数据结构,加上最少的操作符符号集合,使 Python 极其富有表现力
  • 使用异常作为处理错误的主要方法有助于保持代码整洁。
  • Python 程序员倾向于一种受“事后求恕胜于事前防范”(EAFP)理念影响的编程方法,而不是“三思而后行”(LBYL)的概念。这种风格侧重于程序的通常、顺利路径。我们将能够确定如何处理异常。

Python 附带库

Python 的目标是使用一个发行版(即 Python 的默认版本)来解决我们大多数日常问题。为了实现这一目标,Python 包含了一个名为标准库的东西。与 Java 类库一样,它是一个大型实用功能集合,由常量、函数框架和类组成。

Python 促进代码复用

Python 提供了多种选项,允许我们编写可以反复重用的代码,以实现不重复自己 (DRY) 原则。

需要注意的是,Python 包和模块与 Java 包和模块不同。另一个特点是,我们通常可以将所有程序代码分解为 Python 中的模块和包。如果我们想了解这些概念从 Python 开发人员的角度如何工作,我们可以了解更多关于Python 包和模块的信息。

我们可以在 Python 中使用的另一种方法是面向对象编程。我们将在本教程的另一部分讨论这个问题。

此外,我们可以使用装饰器来修改 Python 类、函数或方法。另一种方法是装饰我们的 Python 代码,以便我们只需编写一次功能。然后,它可以从我们装饰的任何类、函数或方法中利用。

Python 易于扩展

支持包和模块是使 Python 通过添加新功能轻松添加新功能的元素之一。还可以通过重写来创建不同的或修改的 Python 常用函数和运算符的行为。我们甚至可以影响类的构建方式。

扩展 Python 最简单的方法是使用纯 Python 编写程序。还可以定义模块,以简化版 Python(称为 Cython)或 CC++ 制作绑定。

我们如何开始探索 Python?

在本教程中,我们将看到一些示例,这些示例将鼓励我们自行探索某些领域或测试 Python 代码片段。作为一名经验丰富的 Java 程序员,我们可能会回忆起我们学习 Java 和安装第一个 Java 开发工具包的最初步骤。如果我们要开始使用 Python,我们将需要安装它。然后,设置一个沙盒,我们可以在其中使用它。

安装 Python

第一步是安装最新版本的 Python。为此,请按照“如何安装 Python”的说明进行操作。

许多 Python 程序员将其代码贡献给与不同 Python 版本兼容的库。他们通常喜欢测试 Python 的预发布版本,而不干扰其正常的 Python 工作。在这些情况下,在同一系统上访问多个不同版本的 Python 会很有益。可以提供此功能的工具是 pyenv,类似于 Java 的 jEnv

创建和使用沙盒

第二步,我们必须建立一个虚拟机,以确保我们能够从一个开放的 Python 生态系统中受益。本节将解释我们需要做什么以及为什么要采取这一步骤。

尽管 Python 拥有功能丰富的标准库,但通过其他包可以获得更多功能,其中大多数是免费的。Python 包索引,也称为 Python Package Index,或简称为 PyPI,是收集和分发包的主要中央存储库。可以使用 pip 命令安装这些包。在安装它们之前,我们必须首先阅读以下两段。

为了避免依赖项版本之间的冲突,通常不建议与其他项目共享我们个人或全局的 Python 安装。实际上,我们每次实验或项目沙箱都需要一个在线环境。

因此,我们的项目彼此保持独立。这种方法还可以避免不同包之间的版本冲突。如果想了解更多关于此过程的信息,可以阅读整篇文章“如何在 Python 中创建虚拟环境”。

选择编辑器或集成开发环境

在设置的最后阶段,选择要选择的编辑器或 IDE。如果已经熟悉 IntelliJ 及其 IDE,那么 PyCharm 似乎是最合适的选择,因为它属于类似的产品线。另一个正在兴起的编辑器是 Visual Studio Code。但是,我们可以从许多其他选择中进行选择。

一旦安装了 Python 并学会了将外部程序安装到虚拟环境中,并选择了编辑器或 IDE,就可以开始使用该语言了。在阅读整个教程时,将有很多练习和测试的机会。

Python 与 Java 有何不同?

通过研究最显著的差异,很容易理解 Python 属于哪种程序。在以下部分中,我们将发现 Python 与 Java 的主要不同之处。

使用缩进进行代码块分组

也许 Python 最引人注目的一点在于其语法。特别是,我们定义其类、函数、流程控制结构以及代码块的方式与我们熟悉的方式不同。在 Java 中,我们使用众所周知的大括号 ( ) 标记代码块。在 Python 中则不同。我们使用缩进级别指示代码块。以下是缩进如何影响代码块分组的示例:

该代码演示了以下新概念:

  • 第 1 行:def 语句是描述一个名为 parity() 的新函数的第一步,该函数接受一个名为 number 的参数。我们应该在类定义块中使用了 def 语句。它将改为启动方法定义。
  • 第 2 行:parity() 内部,函数体在缩进级别开始。我们将字符串“odd number”赋值给第一行中的 result 变量。
  • 第 3 行: 这是一个 if 的开头。
  • 第 4 行: 额外的一行创建了一个新块。当 if 表达式中的条件表达式 number % 2 == 0 评估为 true 时,此块执行。在此示例中,它由一行组成,其中变量“even number”被赋值给 result 变量。
  • 第 5 行: return 语句之前的一行去缩进表示 if 表达式及其块的结束。
  • 第 7 行: 同样,我们注意到 for 循环开始之前的缩进。这是我们达到定义函数块的末尾的点。因此,很明显 for 循环在函数定义块开始的第一行以相同的缩进开始。
  • 第 8 行: for 中也发生了类似的事情。第一个 print() 函数调用是 for 循环块的一部分。
  • 第 9 行: 第二个去缩进的 print() 函数调用不是 for 循环块的一部分。

用户可能已经观察到,在行尾添加冒号 (:) 会开始一个全新的代码块。它缩进一级。该代码块以下一句再次去缩进结束。

代码块应至少包含一个语句。空代码块是不可能的。如果没有所需语句,可以使用“pass 语句”,它什么都不做。

我们可能还知道可以使用井号 ( #) 来添加注释。

上面的例子将产生以下输出:

Number 0 is even number
This is not part of the loop
Number 1 is odd number
This is not part of the loop
Number 2 is even number
This is not part of the loop
Number 3 is odd number
This is not part of the loop

虽然这种定义块的方法乍一看可能显得奇怪,甚至可能让你不适,但实际上,人们习惯它的速度比你现在想象的要快得多。

Python 代码有一些很棒的样式指南,称为 PEP 8。它建议使用四个空格的缩进,并使用空格。样式指南不建议在源代码文件中使用制表符。原因是各种编辑器和系统终端可能会使用不同的制表位位置,并以不同的方式为不同的用户或跨不同的操作系统呈现代码。

从头开始的 Read-Eval-Print Loop

自诞生以来,Python 始终拥有内置的 read-eval-print loop (REPL)。REPL 检查最短的完整表达式、语句或块,然后将其编译为字节码并进行评估。如果评估的代码结果是 None 对象以外的对象,它会生成该对象的清晰版本。有关 None 的解释将在本教程的下一节中给出。

示例

输出

0

输出

0.0

输出

0j

输出

False

输出

'0'

正如我们所见,解释器力求清晰简洁地显示表达式。在上面的示例中,我们可以看到整数、浮点数、复杂数、布尔值以及字符串值以不同的方式呈现。

Java 和 Python 之间的主要区别在于赋值运算符 (=) 的使用。标准的 Python 赋值(使用单个等号)是一个声明,而不是一个表达式,它可能会产生一个值或一个对象。

这就是为什么 REPL 不显示变量零的赋值语句总是被评估为 None。赋值后的行包含变量表达式零,以指示 REPL 打印结果变量,而不考虑表达式。

在 REPL 中,下划线变量 (_) 存储最近表达式的值,前提是它不是 None。以下示例展示了我们如何利用这个特殊变量:

示例

输出

4

输出

4

输出

6

输出

6

输出

7

当我们为 some_var 赋值 7 时,变量 _ 仍保留其值 6。这是因为赋值语句被评估为 None

动态类型和强类型

编程语言的一个关键特征是编译器或解释器如何、以及以何种方式进行类型验证

Python 是一种动态类型语言。这意味着函数、变量和函数返回值的类型是在运行时检查的,而不是像 Java 那样在编译时检查。

Python 同时也是一种强类型语言:

  • 所有对象都有一个与之关联的特定类型。
  • 不同类型之间需要明确的转换。

在本教程中,我们将学习 Python 如何在执行期间测试类型的兼容性以及如何创建兼容的类型:

示例

输出

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
 in 
----> 1 40 + "2"

TypeError: unsupported operand type(s) for +: 'int' and 'str'

输入

输出

42

输入

输出

'402'

输入

输出

'2222222222222222222222222222222222222222'

显然,我们不能简单地将整数添加到现有字符串值中。这在运行时受到保护。如果解释器在运行时检测到导致异常的错误,它会发出警报。REPL 检测异常实例并显示导致不正确表达式的回溯。

为了解决这个问题,将一种类型的对象转换为另一种类型。如果我们希望将两个对象以数字形式连接起来,那么我们将表示数字的字符串转换为在 int() 构造函数中使用的普通数字。如果我们更喜欢使用字符串连接两个对象,我们通过使用 str() 构造函数将数字转换为字符串。

上面 Python 会话的最后一句展示了另一个特性。当我们用数字乘以 sequence 时,我们将得到原始序列的连接版本,该版本乘以我们指定的数字。

尽管 Python 是一种动态类型化的开源语言,但我们可以在代码中提供类型注释

在运行时阶段,Python 不对注释做任何操作,只是使它们可用于自省。但是,静态类型检查工具可用于检测类型声明与类型注释类、函数和变量的实际使用之间的矛盾。

类型注释允许我们在开发过程的早期发现问题。特别是在大型软件项目中,它们有助于使代码易于管理并保持其处于最佳状态。通常,在构建管道中调用验证过程的静态类型检查器部分。大多数 IDE 也使用类型注释。

CPython 与 JIT 编译器

最广泛使用的 Python 实现者很可能是 CPython。它也是参考实现。CPython 可以描述为用 C 创建并可在任何平台上访问的解释器和编译器。与 Java 不同,Python 参考实现没有 JIT 编译器。

CPython 加载一个初始源文件,称为模块。模块分两步加载:

  • 编译: 第一步是 CPython 分析源代码,然后将其编译为“字节码”,这是一组 CPython 解释器可以运行的指令。在有限的范围内,我们可以将编译过程与 Java 的 javac.java 文件编译为 .class 文件进行比较。
  • 执行: 这是 CPython 字节码解释器,也称为 CPython 的虚拟机 (VM),执行第一步中生成的字节码。

与主流 Java VM 实现不同,CPython 不会将字节码转换为对象的本机代码。但是,有不同的 Python 实现以不同的方式运行。

  • 有一个运行在 Java 平台上的 Python 实现,名为 Jython。它运行在 JVM 上,并具有 Java 和 Python 之间直接的互操作性。
  • 还有一个名为 IronPython 的替代方案,它使用 .NET
  • 一个实现使用“即时”(JIT)编译器,称为 PyPy。在平均情况下,PyPy 的速度比 CPython 高 4.2 倍。
  • 最后,GraalVM 是一种极快的运行时,可用于多种编程语言。它提供了对相对当前 Python 版本的实验性支持。

上面的列表并非详尽无遗。Python 网站提供了解决方案和发行版的详细替代列表。

内置函数和运算符重载

作为一名 Java 程序员,我们可能熟悉方法重载的概念。Python 中有一个动态版本,提供了类似的功能。Python 中还有另一种重载,我们可能会觉得更有效率。

我们可以为我们自定义的类设计任何 Python 内置函数或运算符的新行为。

Python 提供了一种实现函数和运算符重载的简单方法。

我们可以通过在课程中创建特殊过程来测试这一点。方法的名称以两个下划线开头。例如,.__len__() 或 .__add__()。具有相同名称的标识符称为 dunder,它是指两个下划线 (__) 的缩写。

如果我们使用具有相应 dunder 方法的对象调用适当的内置方法,Python 会将行为委托给此方法。同样,当我们对带有一个或多个操作数的运算符使用相应的 dunder 技术时,Python 会将行为委托给该方法。

例如,我们可以使用表达式 .__len__() 来实现内置函数 len() 的行为。此外,还可以创建 .__add__() 来为加法运算符 ( +) 提供行为。

此功能允许我们将 Python 代码优雅、简单、富有表现力和简洁的语言不仅应用于标准对象,还应用于自定义对象。

Java 和 Python 的哪些方面相似?

当我们继续探索 Python 时,我们会发现许多与 Java 相似之处。然而,尽管存在这些差异,我们很可能已经观察到 Java 和 Python 之间的一些相似之处。这是因为 Python 和 Java 都受到了其 C 编程语言对应物的影响。

基于类的面向对象

Python 是一种基于类型、面向对象的编程语言。这是 Java 的主要特征之一。然而,这两种语言的面向对象功能列表有所不同,要详细解释它们需要一整篇教程。

幸运的是,我们可以更深入地研究 Python 与 Java 的面向对象编程,以了解 Java 和 Python 在面向对象编程技术方面的区别。还可以阅读 Python 3.0 中面向对象编程的介绍,以增加对该主题的理解。

运算符

运算符是我们观察两种语言共同传承的一种方式。它们中的许多在两种语言中都是相同的。

首先比较著名的 Python 算术运算符和 Java。加法运算符 (+)、乘法运算符 (-)、除法运算符、乘法运算符和模运算符 (%) 在两种语言中几乎具有相同的用途,但整数类操作数的除法运算符除外。

位运算符也是如此:按位或运算符 (|)、按位与运算符 (&)、按位异或运算符 (^),以及一元按位非运算符 (~) 和左移位运算符 (<<) 和右移位运算符 (>>)。

要访问序列中的元素,我们可以使用 Python 的方括号语法 ( []),就像我们使用 Java 的数组访问一样。

字符串格式化

Python 最初提供了基于 printf() 函数族处理 C 编程语言中此问题的字符串格式化功能。这与 Java 的 string.format() 非常相似。Python 中的 % 运算符执行此功能。运算符的左侧包含格式字符串。右侧可以包含位置参数表或带有键参数的字典。

以下会话显示了一些示例:

输入

输出

'Hello, world!'

输入

输出

'The answer is 78.'

输入

输出

'The answer is 78.'

Python 最近采用了其他字符串格式化方法。.format() 字符串方法就是其中之一。在这种情况下,替换字段用大括号 ( 和 ) 标记。这由“The word is value. ”.format(word = "answer", value = 78) 说明。

自 Python 3.6 以来,我们现在可以使用 f 字符串格式化字面量。假设我们有两个作用域值和单词的变量。在这种情况下,表达式“f”。单词等于值“返回与 string.format() 示例相同的结果。

控制流结构

比较 Java 和 Python 时,控制流结构看起来相似。许多控制流概念是直观熟悉的。但是,存在差异。

Python 的 while 循环与 Java 的非常相似。

代码片段逐行将标准输入复制到标准输出,直到它等于“End”。这一行不被复制。相反,文本“READY”被写入,后跟一个换行符。

我们可能已经在这样的结构中看到了海象运算符的附加值。此赋值运算符在所有运算符中具有最低的优先级。当赋值表达式是较大表达式的一部分时,我们通常需要像 Java 一样在其周围加上括号。

Python 的 for 循环与 Java 的 for-each 循环非常相似。我们可以使用类似的逻辑来迭代包含前五个罗马数字的列表。

输入

输出

['I', 'II', 'III', 'IV', 'V']

输入

输出

I
II
III
IV
V

可以发现使用 str.split() 是创建单词字母表的好方法。

有时,我们可能需要一个正在运行的计数器。在这种情况下,我们将使用以下 range():

输入

输出

0
1
2
3
4
5

在这种情况下,“k”在每次迭代中引用请求范围内的下一个值。此值稍后打印。

如果需要遍历数组,同时需要一个正在运行的计数器,请使用 enumerate():

输入

输出

1 I
2 II
3 III
4 IV
5 V

上面的示例展示了如何将前面两个示例的功能组合到一个循环中。伴随计数器默认为 。但是,通过可选的关键字参数 begin,我们可以指定不同的值。

Python 也能理解 break 和 continue 语句。

另一个与 Java 类似的控制流结构是 if 语句。

输入

输出

You have not enough items (0)
You have just enough items (1)
You have more than enough items (2)

如上所示,Python If...else 结构支持 Elif 关键字。这很有用,因为没有简单的 switch...case 语句。

虽然许多代码结构看起来相似,但仍有许多差异。Python 循环和异常捕获结构都支持 else_ 部分。对于上下文管理器,Python 还提供了包含语句的功能。

Python 何时比 Java 更实用,为什么?

大多数时候,我们会选择一种编程语言来满足一个特定的用例,而选择另一种编程语言来满足不同的场景。在比较 Java 与 Python 和其他编程语言时,请考虑以下因素:

  • Java 和 Python 都成功应用于全球最流行的基于 Web 的应用程序中。
  • 此外,我们还可以将 Python 用于 shell 脚本工具。
  • Python 优美的语法、代码可访问性、庞大的库以及各种其他工具可以实现快速开发。它可能只需要 Java 代码一半的行数就能达到同样的效果。
  • 由于标准 Python 不需要链接或编译步骤,因此每当我们更改代码时,我们都可以立即看到结果。这也加快了开发过程。
  • 对于大多数通用应用程序,普通 Java 的执行速度高于 Python。
  • Python 可以用 C 和 C++ 扩展,相对而言不费吹灰之力。在一定程度上,这可以减少执行速度的差异。

在某些应用程序中,例如分析、数据建模、机器学习或人工智能,执行速度至关重要。为此目的设计的最流行的第三方应用程序以编译为本机代码的编程语言编写。在这些情况下,Python 似乎是最佳选择。

结论

在本教程中,我们学习了 Python 并了解了这种编程语言的特点。我们了解了 Java 与 Python 之间的异同。

现在我们有了一个坚实的基础,可以快速开始使用 Python。此外,我们对在哪些场景和领域可以使用 Python 有了扎实的基础知识,并概述了下次可以使用的资源。

在本教程中,我们学习了:

  • Python 编程语言的语法。
  • Python 中有许多标准数据类型。
  • Java 和 Python 中有哪些方面是相同的?
  • 在哪里可以找到 Python 文档和针对您的主题的特定教程?
  • 如何开始使用 Python?
  • 如何通过 Python REPL 立即查看结果?