VS2010-2015对C++11/14/17特性的支持(vs2012支持c++11)
726
2022-05-30
目录
Python 来自哪里?
Python 的 Philosophy 是什么?
Python 代码可读
Python Comes With Batteries Included
Python 促进代码重用
Python 易于扩展
如何开始发现 Python?
安装 Python
创建沙箱并使用它
选择编辑器或集成开发环境
Python 与 Java 有何不同?
代码块分组的缩进
从头开始的读取-评估-打印循环
动态类型和强类型
CPython 与 JIT 编译器
内置函数和运算符重载
集合函数处理的好语法
万物皆对象
Java 和 Python 的哪些方面相似?
基于类的面向对象
Operators
字符串格式
控制流结构
Java 与 Python:什么是高级本机数据类型?
Numeric Types and Their Operators
基本序列类型
字典
Sets
字符串
字节
布尔值
None
More Container Data Types
有哪些特定用途的资源?
Python 何时会比 Java 更有用,为什么?
结论
其他资源
Python 是一种通用的编程语言。您可以通过考虑其学习的平易性及其对数据分析、机器学习和 Web 开发的高度适用性来了解它在过去几年中的增长。但它是一种什么样的编程语言?比较 Java 与 Python 时有哪些区别?你能用它做什么?它真的像某些人声称的那样“容易学习”吗?
在本教程中,您将从 Java 的角度探索 Python。阅读之后,您将能够决定 Python 是否是解决您的用例的可行选择,并能够欣赏何时可以将 Python 与 Java 结合使用来解决某些类型的问题。
在本教程中,您将了解:
Python 编程语言的通用语法
最相关的标准数据类型
的差异和相似之处VS Python的Java中
高质量 Python文档和教程的资源
一些 Python 社区最喜欢的框架和库
从头开始Python 编程的方法
本教程适用于熟悉 Java 的内部工作原理、概念、术语、类、类型、集合框架等的软件开发人员。
您根本不需要任何 Python 经验。
Python 来自哪里?
Python 是由Guido van Rossum开发的一种编程语言。1989 年,他正在寻找一个可以让他在 1989 年圣诞节假期里忙得不可开交的业余编程项目,于是他开始开发 Python 解释器。
Python 起源于多种语言:ABC、C和Modula-3。它基本上是一种面向对象的命令式编程语言。
根据您的偏好和所需的功能,它可以应用于完全面向对象的风格或具有函数的过程编程风格。本教程稍后将介绍面向对象的功能。
注意:为了清楚起见,从 Java 的角度来看,Python 函数类似于静态方法,您不一定需要在类中定义它们。稍后,您将看到 Python 函数定义的示例。
此外,更函数式的编程风格也是完全可能的。要了解更多信息,您需要探索Python 的函数式编程能力。
2021 年初,TIOBE第四次宣布 Python 为年度编程语言。截至 2021 Octoverse 报告,Python 被存储库贡献者列为 GitHub 上第二大最受欢迎的语言。
Python 的哲学是什么?
很快,您将在本部分之后的部分中动手操作 Python 。但是,首先,您将通过了解一些可以追溯到 Python 哲学的特性来探索为什么值得更好地了解 Python。
Java 和 Python 背后的一些想法是相似的,但每种编程语言都有其独特的特征。Python 的哲学被捕获为 19 条指导原则的集合,Python之禅。Python 隐藏了一些复活节彩蛋,其中之一是 Python 之禅。考虑在 Python read-eval-print loop (REPL) 中发出以下命令时会发生什么:
>>>
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
虽然您不应该从字面上理解上面的陈述,但其中一些与您接下来要介绍的特征直接相关。
注意: Python read-eval-print 循环将在本教程的后面部分进行解释。
通过考虑 Python Zen of Python 的指导原则,您将对如何使用该语言有一个很好的了解。
Python 代码可读
如果您具有 Java 背景并且查看 Python 代码的典型片段,您可能会认为您正在查看伪代码。有几个因素会导致这种情况:
缩进用于语句分组。这使得代码块更短并促进了统一的编码风格。稍后您将找到有关此主题的更多信息。
一些内置的高级数据结构,结合一组适度的运算符符号,使 Python 非常具有表现力。
选择使用异常作为处理错误的主要方式可以保持代码整洁。
Python 程序员更喜欢受这种概念启发的编码风格,即请求宽恕比许可 (EAFP) 更容易,而不是跃跃欲试(LBYL)概念。这种风格强调程序的正常、愉快的路径,然后您将弄清楚如何处理任何异常。
您可以在本教程以及其他链接资源中找到一些示例,说明这在实践中的表现。
Python Comes With Batteries Included
Python 的目标是您只需使用 Python 的标准发行版就可以解决大多数日常问题。为此,Python 包含了所谓的标准库。就像Java 类库一样,它是一个广泛的有用工具集合,包括常量、函数、类和框架。
要进一步了解 Python 标准库,请查看Python 文档的Python 教程中标准库简介的第一部分和第二部分。
Python 促进代码重用
Python 提供了多种功能,使您能够开发可以在不同地方重用的代码,以应用不要重复自己 (DRY)原则。
一个特点是您通常将代码分解为Python 中的模块和包。但是请注意,Python 模块和包不同于 Java 模块和包。如果您想从 Python 开发人员的角度了解更多关于这些概念的信息,您可以阅读Python 模块和包。
您可以在 Python 中使用的另一种技术是面向对象编程。您将在本教程的稍后部分对此进行探讨。
您还可以使用装饰器来修改 Python 函数、类或方法。这是另一种技术,因此您只能对功能进行一次编程,之后就可以从您修饰的任何函数、类或方法中使用它。
Python 易于扩展
模块和包的支持是使用新功能轻松扩展 Python 的要素之一。您还可以通过重载Python 标准运算符和函数来定义新的或改编的行为。甚至可以影响类的创建方式。
扩展 Python 最直接的方法是用纯 Python 编写代码。您还可以通过使用简化的 Python 方言(称为 Cython)或 C 或 C++ 中的绑定来定义模块。
如何开始发现 Python?
在本教程中,您将找到一些示例,这些示例可能会鼓励您探索某些事物或亲自尝试 Python 代码片段。作为 Java 开发人员,您可能还记得熟悉 Java 和安装第一个 Java 开发工具包的第一步。同样,如果您想开始使用 Python,首先需要安装它,然后创建一个沙箱,您可以在其中安全地进行实验。
已经有几个教程解释了如何执行此操作,因此接下来的小节将为您提供这些资源。
安装 Python
第一步是安装最新版本的 Python。为此,请遵循此Python 3 安装和设置指南。
另一个可以查找安装说明的地方是官方 Python 下载页面。
注意:确保您安装了最新版本的 Python。在撰写本教程时,最新版本是3.10.x 系列的最新补丁版本。本教程中显示的代码片段应该都适用于此版本的 Python。
许多 Python 开发人员为支持各种 Python 版本的库做出了贡献,他们通常更喜欢在不干扰正常 Python 工作的情况下试用 Python 的预发布版本。在这些情况下,在同一台机器上访问多个版本的 Python 会很方便。提供该功能的工具是pyenv,可与 Java 的jEnv相媲美。
创建沙箱并使用它
第二步,您应该设置一个虚拟环境,以便您可以安全地利用开源 Python 生态系统。本节说明您应该如何以及为什么要这样做。
尽管 Python 附带了一个具有各种功能的广泛标准库,但还有更多功能以外部包的形式提供,其中绝大多数是开源的。在Python包索引,或PyPI中的简称,是主要的中央资料库,收集和提供这些软件包。您可以使用该pip命令安装软件包。但是,在您这样做之前,请先阅读接下来的两段。
为避免依赖版本冲突,您通常不应在项目之间共享全局或个人 Python 安装。在实践中,您会为每个项目或实验沙箱提供一个虚拟环境。
这样,您的项目就可以相互独立。这种方法还可以防止包之间的版本冲突。如果您想了解有关此过程的更多信息,则可以阅读有关如何创建和激活虚拟环境的详细信息。
选择编辑器或集成开发环境
作为设置的最后一步,决定您要使用哪个编辑器或 IDE。如果您习惯了 IntelliJ,那么PyCharm似乎是合乎逻辑的选择,因为它属于同一产品线。另一个流行的编辑器是Visual Studio Code,但您也可以从许多其他选项中进行选择。
在您安装 Python、了解如何将外部包安装到虚拟环境中并选择编辑器或 IDE 后,您可以开始尝试该语言。当您通读本教程的其余部分时,您会发现大量的实验和练习机会。
Python 与 Java 有何不同?
通过查看最显着差异的地方,您可以快速了解 Python 是哪种编程语言。在以下小节中,您将了解 Python 与 Java 不同的最重要方式。
代码块分组的缩进
也许 Python 最引人注目的特性是它的语法。特别是,您指定其函数、类、流控制构造和代码块的方式与您可能习惯的方式大不相同。在 Java 中,您用众所周知的花括号 ({和})表示代码块。但是,在 Python 中,您可以通过缩进级别来指示代码块。下面是一个演示缩进如何确定代码块分组的示例:
1def parity(number): 2 result = "odd" # Function body 3 if number % 2 == 0: 4 result = "even" # Body of if-block 5 return result # Not part of if-block 6 7for num in range(4): # Not part of function 8 print("Number", num, "is", parity(num)) # Body of for-loop 9print("This is not part of the loop") # Not part of for-loop
该代码显示了一些新概念:
第 1 行:该def语句开始定义一个名为的新函数parity(),该函数接受一个名为 的参数number。请注意,如果该def语句出现在类定义块中,它将改为启动一个方法定义。
第 2 行:在 内parity(),函数体以缩进级别开始。第一个语句是将"odd"字符串分配给result变量。
第 3 行:您可以在此处看到if语句的开头。
第 4 行:额外的缩进开始一个新块。当if语句的条件表达式number % 2 == 0,计算结果为真时执行此块。在示例中,它仅包含您分配"even"给result变量的一行。
5号线:在DEDENT语言先于return声明中的标记结束if语句及其相关的块。
第 7 行:同样,您会看到for循环开始之前的 dedent 。因此,for循环开始于与函数定义块在第一行的开始相同的缩进级别。它标志着函数定义块的结束。
第 8 行:您会在for循环中看到同样的情况再次发生。第一个print()函数调用是for循环块的一部分。
第 9 行:第二个 dedentedprint()函数调用不是for循环块的一部分。
您可能已经注意到,:一行末尾的冒号 ( ) 引入了一个新的代码子块,它应该缩进一级。当下一条语句再次缩进时,此代码块结束。
一个代码块必须至少包含一个语句。一个空的代码块是不可能的。在极少数不需要任何语句的情况下,您可以使用passstatement,它什么都不做。
最后,您可能还注意到可以使用井号 ( #) 进行注释。
上面的示例将产生以下输出:
Number 0 is even Number 1 is odd Number 2 is even Number 3 is odd This is not part of the loop
尽管这种定义块的方式乍一看似乎很奇怪,甚至可能会吓到您,但经验表明人们会比您现在想象的更早习惯它。
有一个有用的 Python 代码样式指南,称为PEP 8。它建议使用四个位置的缩进级别,使用空格。样式指南不建议在源代码文件中使用选项卡。原因是不同的编辑器和系统终端可能使用不一致的制表位位置,并为不同的用户或不同的操作系统呈现不同的代码。
注意:风格指南是Python Enhancement Proposal 的一个例子,简称PEP。PEP 不仅包含提案,而且还反映了实现规范,因此您可以将 PEP 与 Java 的 JEP 和 JSR 的联合进行比较。PEP 0列出了 PEP 的索引。
您可以在 PEP 8 中找到很多有趣的信息,包括 Python命名约定。如果您仔细阅读它们,您会发现它们与 Java 的略有不同。
从头开始的读取-评估-打印循环
从一开始,Python 就一直有一个内置的read-eval-print loop (REPL)。REPL 读取尽可能短的完整语句、表达式或块,将其编译为字节码,并对其进行评估。如果被评估的代码返回一个对象而不是None对象,它会输出这个对象的明确表示。您将在本教程的None 后面找到 的解释。
注意:您可以将 Python REPL 与Java 的 JShell (JEP 222) 进行比较,后者从 JDK 9 开始可用。
下面的片段展示了 Python 的 REPL 是如何工作的:
>>>
>>> zero = int(0) >>> zero 0 >>> float(zero) 0.0 >>> complex(zero) 0j >>> bool(zero) False >>> str(zero) '0'
如您所见,解释器总是试图明确地显示结果表达式值。在上面的示例中,您可以看到integer、 floating point 、complex、Boolean和string值是如何以不同方式显示的。
Java 和 Python 之间的区别涉及赋值运算符 ( =)。使用单个等号的常规 Python 赋值是语句而不是表达式,它会产生一些值或对象。
这解释了为什么 REPL 不打印对变量的赋值zero:语句总是计算为None。赋值之后的行包含变量表达式zero,以指示 REPL 无论如何显示结果变量。
注意: Python 3.8 引入了赋值表达式运算符 ( :=),也称为walrus 运算符。它为变量赋值,但与常规赋值不同的是,它像在表达式中一样计算变量。这类似于 Java 中的赋值运算符。但是请注意,它不能与常规赋值语句完全互换。它的范围实际上是相当有限的。
在 REPL 中,下划线特殊变量 ( _) 保存最后一个表达式的值,前提是它不是None。以下片段显示了如何使用此特殊变量:
>>>
>>> 2 + 2 4 >>> _ 4 >>> _ + 2 6 >>> some_var = _ + 1 >>> _ 6 >>> some_var 7
在您指定的值7来some_var,特变_仍持有价值6。那是因为赋值语句的计算结果为None。
动态类型和强类型
编程语言的一个重要特征是语言解释器或编译器执行类型验证的时间、方式和程度。
Python 是一种动态类型语言。这意味着变量、函数参数和函数返回值的类型是在运行时而不是在编译时检查的,这与 Java 不同。
Python 同时也是一种强类型语言:
每个对象都有与之关联的特定类型。
不兼容的类型之间需要显式转换。
在这里,您将探索 Python 如何在运行时检查类型兼容性以及如何使类型兼容:
>>>
>>> 40 + "2" Traceback (most recent call last): File "
您会注意到,您不能仅将整数值添加到字符串值中。这在运行时受到保护。当解释器检测到运行时错误时,它会生成一个异常。REPL 捕获Exception实例并显示导致错误表达式的回溯。
要解决此问题,请将一种类型转换为另一种类型。如果要将两个对象作为数字相加,则可以使用int()构造函数将表示数字的字符串转换为普通数字。如果您想将两个对象连接为字符串,则可以使用str()构造函数将数字转换为字符串。
上面 Python 会话的最后一行显示了另一个功能。通过将一个序列与一个数字相乘,您可以获得原始序列的连接结果,并按给定数字重复。
尽管 Python 是一种动态类型语言,但可以为代码提供类型注释。
在运行时,Python 不会对这些注解做任何事情,只是让它们可用于自省。但是,存在静态类型检查器工具,可以检测类型声明与类型注释函数、类和变量的实际使用之间的不一致。
注意:如上所述,Python 运行时使类型注释可用于代码自省。一些库会使用此信息,例如FastAPI。
类型注释可帮助您在代码开发周期的早期阶段检测错误。特别是在大型软件项目中,它们可以帮助您使代码更易于维护并使代码库保持良好状态。您通常会调用静态类型检查器作为构建管道中验证步骤的一部分。大多数 IDE 也使用类型注释。
CPython 与 JIT 编译器
与 Java 不同,Python 的参考实现没有 JIT 编译器。到目前为止,最常用的 Python 实现是CPython。这也是参考实现。CPython是一个用 C 编写的编译器和解释器,几乎可以在所有可以想象的平台上使用。
CPython分两步加载一个名为module的源文件:
编译:首先,CPython读取代码并编译成字节码,字节码是CPython字节码解释器可以执行的指令序列。在有限的范围内,您可以将编译阶段与 Javajavac将.java文件编译为文件的方式进行比较.class。
执行: CPython 字节码解释器——换句话说,CPython 的虚拟机 (VM) ——随后从第一步开始执行字节码。
注意:与 Java 不同,您不能假设相同的 Python 字节码可以与其他 Python 实现一起使用,甚至可以在同一 Python 实现的不同版本之间使用。但是,它有助于减少加载模块所需的时间。
在编译的模块是,如果可能的话,保存在高速缓存目录中。
不像主流的Java虚拟机的实现,CPython中并没有在后来编译成字节码原生对象代码。但是,还有其他不同的 Python 实现:
Java 平台有一个名为Jython的 Python 实现。它在 JVM 中运行,并且在 Java 和 Python 之间存在直接的互操作性。
同样,有一个名为IronPython的版本可以在 .NET 平台上运行。
有一个使用名为PyPy的即时 (JIT)编译器的实现。平均而言,PyPy 比 CPython 快 4.2 倍。
最后,GraalVM是一个支持多种编程语言的高性能运行时。它为相当新的 Python 版本提供实验性支持。
上面的列表并不详尽。Python 站点包含替代实现和分发的列表。
内置函数和运算符重载
作为Java开发人员,你可能知道的长期超载的方法重载。虽然Python 中有一个动态等价物,它提供了一些类似的功能,但 Python 中还有另一种重载,您可能会发现它更有用。
您可以为任何符合条件的 Python 内置函数和运算符定义自定义类的新行为。
注意:在这种情况下,您可以将符合条件的函数和运算符视为允许您重载其行为的函数和运算符。
Python 提供了一种可访问的方式来实现函数和运算符重载。
您可以通过在类中定义特殊命名的方法来尝试此操作。此类方法的名称以两个下划线开头和结尾,例如.__len__()或.__add__()。具有这样名称的标识符称为dunder,双下划线( __) 的缩写。
当您使用存在相应 dunder 方法的对象调用符合条件的内置函数时,Python 会将行为委托给此方法。同样,当您使用一个或多个操作数包含相应 dunder 方法的运算符时,Python 会将行为委托给该方法。
例如,您可以定义.__len__()为内置len()函数提供行为。同样,您可以定义.__add__()为加法运算符 ( +)提供行为。
这个特性使得不仅可以将 Python 代码的漂亮、富有表现力和简洁的语法应用于标准对象,还可以应用于自定义对象。
集合函数处理的好语法
在Java中,你可能已经通过结合调用构造名单map(),filter()和lambda表达式。您可以在 Python 中使用相同的函数和技术执行相同的操作。使用这些结构并不总是会产生最易读的代码片段。
Python 为列表和其他集合的这种基本功能操作提供了一种优雅的替代语法。您可以对列表使用列表理解,对其他集合使用其他类型的理解。如果您想更多地了解 Python 中的推导式,那么您可以探索何时使用列表推导式。
万物皆对象
在 Java 中,并非所有东西都是对象,尽管事实上唯一可以放置代码的地方是在 Java 类中。例如,Java 原语42不是对象。
就像 Java 一样,Python 也完全支持面向对象的编程风格。与 Java 不同的是,在 Python中一切都是对象。Python 对象的一些示例是:
数值
文档字符串
函数和方法
模块
堆栈回溯
字节编译的代码对象
班级本身
因为它们是对象,所以您可以将所有这些存储在变量中,传递它们,并在运行时内省它们。
注意:正如你在上面读到的,类是对象。由于根据定义对象是类的实例,因此类也必须是某物的实例。
事实上,这些是元类的实例。标准元类是type,但您可以创建替代元类,通常是通过派生自type来改变创建类的方式。
元类与重载内置函数和运算符的能力相结合,是使 Python 成为多功能编程工具包的一部分。它们允许您创建自己的可编程的类和实例的附加或替代行为领域。
Java 和 Python 的哪些方面相似?
尽管存在差异,但您可能已经发现 Java 和 Python 之间的一些相似之处。这是因为 Python 和 Java 都受到 C 编程语言的启发。在您继续探索 Python 的过程中,您会发现与 Java 的更多相似之处。
基于类的面向对象
Python 是一种基于类的、面向对象的编程语言,这也是 Java 的主要特性之一。但是,这两种语言的面向对象特性集不同,要足够详细地解决这些问题,需要专门的教程。
幸运的是,您可以深入研究 Python 与 Java 中的面向对象编程,以大致了解 Java 和 Python 在面向对象编程构造方面的差异。您还可以查看Python 3 中面向对象编程的概述,以扩展您对该主题的了解。
Operators
您可能会注意到这些语言的共同遗产的一个方面是它们如何使用运算符。其中许多在两种语言中具有相同的含义。
首先,比较 Java 和 Python 中众所周知的算术运算符。加法运算符 ( +)、减法运算符 ( -)、乘法运算符 ( *)、除法运算符 ( /) 和模运算符 ( %) 在两种语言中的用途几乎相同——除了类整数操作数上的除法运算符。
这同样适用于按位运算符:按位 OR 运算符 ( |)、按位 AND 运算符 ( &)、按位 XOR 运算符 ( ^) 和一元按位非运算符 ( ~),以及用于左移的按位移位运算符 ( <<) 和右移 ( >>)。
您可以[]在 Python 中使用方括号语法 ( ) 来访问序列的元素,就像您可以使用 Java 的数组访问一样。
后面关于数据类型的部分提供了有关这些和一些附加运算符的更多详细信息。或者,如果您现在想了解更多关于它们的信息,您可以阅读Python 中的运算符和表达式。
字符串格式
最初,Python 根据printfC 编程语言中函数系列的处理方式提供字符串格式化功能。这类似于 Java 的String.format(). 在 Python 中,%运算符执行此功能。运算符的左侧包含格式字符串,右侧包含位置参数的元组或键控参数的字典。
注意:您将在本教程后面看到更多关于元组和字典的内容。
以下会话显示了一些示例:
>>>
>>> "Hello, %s!" % "world" # %-style, single argument 'Hello, world!' >>> "The %s is %d." % ("answer", 42) # %-style, positional 'The answer is 42.' >>> "The %(word)s is %(value)d." \ ... % dict(word="answer", value=42) # %-style, key-based 'The answer is 42.'
最近,Python 接受了其他格式化字符串的方法。一种是使用.format()字符串方法,其中替换字段用大括号 ( {}) 表示。这方面的一个例子是"The {word} is {value}.".format(word="answer", value=42)。
从 Python 3.6 开始,您还可以使用格式化字符串文字,也称为f-strings。假设您在范围内有两个名为word和 的变量value。在这种情况下,表达式f"The {word} is {value}."为您呈现与.format()上面示例相同的字符串。
控制流结构
比较 Java 与 Python 时,控制流结构是相似的。这意味着您可能直观地识别出许多控制流结构。然而,在更详细的层面上,也存在差异。
Pythonwhile循环类似于 Java 的:
while (word := input("Enter word: ")) != "END": print(word) print("READY")
代码片段逐行将标准输入复制到标准输出,直到该行等于"END"。该行不会被复制,而是"READY"会写入文本,然后是换行符。
您可能已经注意到海象运算符在这样的构造中的附加值。此赋值表达式运算符的优先级是所有运算符中最低的。这意味着当赋值表达式是较大表达式的一部分时,您经常需要在其周围添加括号,就像在 Java 中一样。
注意: Python 没有do {...} while (...)循环结构。
Pythonfor循环类似于 Java 的 for-each 循环。这意味着,例如,如果您想遍历前五个罗马数字的列表,您可以使用类似的逻辑对其进行编码:
>>>
>>> roman_numerals = "I II III IV V".split() >>> roman_numerals ['I', 'II', 'III', 'IV', 'V'] >>> for numeral in roman_numerals: ... print(numeral) ... I II III IV V
您可能会注意到 usingstr.split()是一种创建单词列表的便捷方式。
注意:它不仅是list您可以通过这种方式迭代的实例,而且是任何可迭代的.
有时,您可能需要一个运行计数器。在这种情况下,你会使用range():
>>>
>>> for i in range(5): ... print(i) ... 0 1 2 3 4
在这个例子中,i每次迭代都引用请求范围的下一个值。随后打印该值。
在极少数情况下,您想要迭代一个集合,同时想要在它旁边有一个运行计数器,您可以使用enumerate():
>>>
>>> for i, numeral in enumerate("I II III IV V".split(), start=1): ... print(i, numeral) ... 1 I 2 II 3 III 4 IV 5 V
上面的示例显示了在一个循环中组合的前面两个示例的功能。默认情况下,伴随的计数器从零开始,但使用可选的关键字参数start,您可以指定另一个值。
注:退房的Python枚举():简化环通设有专柜,如果你想了解更多关于Python循环和enumerate()。
Python 也理解breakandcontinue语句。
另一个类似于 Java 的控制流结构是以下if语句:
>>>
>>> for n in range(3): ... if n <= 0: ... adjective = "not enough" ... elif n == 1: ... adjective = "just enough" ... else: ... adjective = "more than enough" ... print(f"You have {adjective} items ({n:d})") ... You have not enough items (0) You have just enough items (1) You have more than enough items (2)
如上所述,Pythonif ... else构造还支持elif关键字,这很有用,因为没有简单的switch ... case语句。
注意:最近发布的 Python 3.10 版本包含一个名为结构模式匹配的新特性,它引入了match和case关键字,但它的行为与 Java 的switchstatement 有很大不同。
这个新语言特性的灵感来自Scala的模式匹配语句,Scala 是另一种运行在 JVM 上的编程语言。
尽管许多编码结构表面上看起来很相似,但仍然存在许多差异。例如,Python 循环以及异常捕获结构支持else:一部分。此外,Python为上下文管理器提供了一条with语句。
Java 与 Python:什么是高级本机数据类型?
在以下小节中,您将找到 Python 标准类型的简要概述。重点是这些类型或其关联运算符与 Java 的不同之处,或者它们与相应的 Java 集合类的比较。
数字类型及其运算符
Python 提供了多种数字类型供您选择以适合您的特定应用领域。它内置了三种数字类型:
如果比较这两种语言,您会发现 Python 整数可以包含任意长值,仅受机器可用的(虚拟)内存量限制。您可以将它们视为固定精度本机整数(或原始整数类型,如 Java 所称)和 JavaBigInteger数字的智能混合,结果如下:
您拥有任意精度整数的所有便利,并且可以对它们使用所有众所周知的符号运算符。
当值足够小以允许这样做时,Python对提供的值应用快速固定精度整数算法。
通过使用前缀0x、0o和0b,您可以分别将 Python 整数指定为十六进制、八进制和二进制常量。
注意:这意味着八进制数的前缀不是只有一个或多个前导零 ( 0),这与 Java 不同。
比较著名的算术运算符+, -, *, /, 以及%在 Java 与 Python 中,它们在两种语言中具有相同的含义,除了类整数类型的除法运算符。应用于操作数的truediv运算符 ( /)在 Python 中int产生一个float值,这与 Java 不同。Python 具有用于除法的floordiv运算符 ( //),可向下舍入到最接近的整数,类似于/Java 中的除法运算符 ( ):
>>>
>>> 11 / 4 # truediv 2.75 >>> 11.0 // 4 # floordiv, despite float operand(s) 2.0
此外,Python**为求幂提供了双星号运算符 ( ) 作为双参数pow()函数的替代方法。所述MATMUL运算符(@)被保留作为用于由外部的包提供的类型的额外的操作员,旨在作为一个方便的符号为矩阵乘法。
Python 和 Java 都采用了 C 编程语言中的按位运算符。这意味着按位运算符(|、&、^和 一元~)在两种编程语言中具有相同的含义。
如果您想在负值上使用这些运算符,那么很高兴知道在 Python 中,整数在概念上无限大的空间中表示为二进制补码值来保存位。这意味着负值在概念上有无限多的前导1位,就像正数在概念上有无限多的前导0位:
>>>
>>> bin(~0) '-0b1' >>> bin(~0 & 0b1111) # ~0 is an "infinite" sequence of ones '0b1111'
上面的代码片段表明,无论您选择哪个值,如果您将此值与常量 进行按位与运算~0,则结果值等于所选值。这意味着常量在~0概念上是一个无限的1位序列。
的比特移位操作符(<<和>>)也是可用的。但是,没有与 Java 的按位零填充右移运算符 ( >>>)等效的运算符,因为这在具有任意长整数的数字系统中毫无意义。没有最重要的一点触手可及。两种语言之间的另一个区别是 Python 不允许以负移位计数移位位。
Python 标准库也提供其他数字类型。有decimal.Decimal十进制定点和浮点运算,可与 Java 的BigDecimal. 有一个fractions.Fraction用于有理数的类,可与Apache Commons Math Fractions相媲美。请注意,这些类型不属于内置数字类型。
基本序列类型
序列类型是容器,您可以在其中使用整数索引访问它们的元素。字符串和字节序列也是序列类型。稍后将介绍这些内容。Python 内置了三种基本的序列类型:
如您所见,列表和元组初始值设定项之间的语法差异在于方括号 ( []) 与圆括号 ( ())。
Python列表类似于 Java 的ArrayList,并且它是可变的。您通常将这种容器用于同类集合,就像在 Java 中一样。然而,在 Python 中,可以存储不相关类型的对象。
一个元组,而另一方面,更类似于一个不可改变的一个版本Pair般类在Java中,除了它的条目,而不是两个任意数量。空括号 ( ()) 表示空元组。结构 like(3,)表示包含单个元素的元组。在这种情况下,单个元素是3。
注意:您是否注意到tuple只有一个元素的a 的特殊语法?请参阅以下会话以发现差异:
>>>
>>> (3,) (3,) >>> type(_)
如果您没有添加尾随逗号,则表达式将被解释为括号内的对象。
一个范围得到的数字序列,你通常在循环使用。您已经在本教程的前面看到了一个示例。如果您想了解有关 Python 范围的更多信息,可以查看本 range() 函数指南。
要从序列中选择一个元素,您可以在方括号之间指定从零开始的索引,如some_sequence[some_index]。负索引从末尾开始向后计数,因此-1表示最后一个元素。
您还可以从序列中选择一个切片。这是对零个、一个或多个元素的选择,产生与原始序列类型相同的对象。你可以指定一个start,stop以及step价值,也被称为步幅。切片语法的一个例子是some_sequence[
所有这些值都是可选的,如果没有另外指定,则采用实际的默认值。如果您想了解更多关于列表、元组、索引和切片的信息,阅读Python 中的列表和元组将会很有帮助。
对于正索引,Python 语法类似于在 Java 数组中选择元素的方式。
您可以使用加号运算符 ( +)连接大多数序列,并使用星号运算符 ( *)重复它们:
>>>
>>> ["testing"] + ["one", "two"] * 2 ['testing', 'one', 'two', 'one', 'two']
您无法使用范围完成串联或序列重复,但可以对它们进行切片。例如,尝试range(6, 36, 3)[7:2:-2]并考虑结果。
字典
Python 中的字典dict类似于 Java 中的LinkedHashMap. dict 初始值设定key: value项常量的语法是花括号 ( {})之间以逗号分隔的条目序列。这方面的一个例子是{"pi": 3.14, "e": 2.71}。
要从 dict 或任何其他映射中选择元素,您可以在方括号 ( [])之间指定键,如math_symbols["pi"]. 键和值都可以是任何对象,但键需要是hashable,这意味着它们通常是不可变的——或者至少应该表现得像不可变的对象。键不必都是相同类型的,尽管它们通常是。这同样适用于价值观。
有关其他信息,您可以阅读有关Python 中字典的更多信息,或查看有关映射类型的 Python 文档。
Sets
Python 还提供了set。您可以{"pi", "e"}使用类似的语法或通过使用set()构造函数语法,使用可迭代对象作为参数来初始化集合。要创建空集,请使用表达式,set()因为文字{}已经提供给字典。
集合在底层实现中使用散列。当您迭代一个集合时,请考虑到这些项目将以明显随机的顺序出现,就像在 Java 中一样。此外,顺序甚至可能在不同的 Python 调用之间发生变化。
一些运算符已被重载用于集合上的操作。有关详细信息,您可以阅读有关Python 中集合的更多信息。
字符串
就像在 Java 中一样,Python 中的字符串是不可变的 Unicode 元素序列。字符串字面量在双引号 ( ")之间指定,也可以在单引号 ( ')之间指定,这与 Java 不同。
字符串的两个示例是"foo"和'bar'。定义字符串时,不同的引号不一定具有任何不同的含义。但是,您应该注意,如果您将任何引号本身用作字符串的一部分,并且它们恰好也是字符串的分隔符,则您必须对它们进行转义。
与 Java 中一样,\Python 中的反斜杠 ( ) 是引入转义序列的字符。Python解释器识别Java也称为转义序列,如\b,\n,\t,和从C编程语言中的一些额外的。
默认情况下,Python 假定您的 Python 源文件使用 UTF-8 编码。这意味着您可以将 Unicode 文字直接放入字符串中,就像"é". 您还可以使用其代码点的 16 位或 32 位十六进制表示。对于"é",您可以使用\u00E9或\U000000E9转义序列来执行此操作。请注意小写\u和大写\U转义序列之间的区别。最后,还可以提供其 Unicode 描述,例如\N{Latin Small Letter E with acute}.
您甚至可以在 Python 标识符中使用 Unicode 字符,但问题是这是否是可取的做法。
如果你在字符串前加上r,比如 in r"raw\text",那么反斜杠就失去了它的特殊意义。当您要指定正则表达式时,这尤其方便。
您还可以将字符串三重引用作为创建多行字符串的便捷方式,如下例所示:
>>>
>>> s = """This is a ... multiline ... string. ... """ ... >>> for line in s.splitlines(): ... print(repr(line)) ... 'This is a' ' multiline' ' string.' ' '
您可以将这种类型的字符串与 Java文本块 (JEP 378) 进行比较,尽管具有其他语法限制和另一种空格(制表符、空格和换行符)的保留。
字节
在 Java 中,如果您需要存储二进制数据而不是text,您可能会使用ByteBuffer,它为您提供可变对象。在 Python 中,bytearray对象提供类似的功能。
与 Java 不同,Python 还提供了一种bytes类型来存储不可变的二进制数据。字节字面量看起来与字符串字面量非常相似,除了你在字面量前加上b. 字符串包含一个.encode()将它们转换为字节序列的方法,一个bytes对象包含一个.decode()将其转换为字符串的方法:
>>>
>>> bytes(4) # Zero-filled with a specified length b'\x00\x00\x00\x00' >>> bytes(range(4)) # From an iterable of integers b'\x00\x01\x02\x03' >>> b = "Attaché case".encode() # Many different codecs are available >>> b b'Attach\xc3\xa9 case' >>> b.decode() # Decode back into a string again 'Attaché case'
如果未指定编解码器,则默认 UTF-8 编解码器用于编码字符串和解码字节。需要时,您可以从提供各种文本和字节转换的大量编解码器列表中进行选择。
Pythonbytes对象还有一个.hex()方法可以生成一个字符串,该字符串将以十六进制形式列出内容。对于反向操作,您可以使用.fromhex() 类方法bytes从十六进制字符串表示构造一个对象。
布尔值
False和True是boolPython中的两个实例对象。在数字方面,True计算结果为1和False到0。这意味着True + True评估为2.
在Python中的布尔逻辑运算符是从Java的不同&&,||以及!运营商。在Python,这些都是保留关键字and,or和not。
您可以在下表中看到这一点:
与 Java 类似,布尔运算符andand存在短路求值行为or,其中 Python 解释器从左到右懒惰地求值操作数,直到它可以确定整个表达式的真实性。
与 Java 的另一个相似之处是解释器产生最后一个评估的子表达式作为结果。因此,您应该意识到andoror表达式的结果不一定会产生bool实例对象。
所有的Python对象要么有一个falsy或truthy值。换句话说,当您将 Python 对象转换为 时bool,结果是明确定义的:
等于的数值0转换为False,True否则转换为。
空容器、集合、字符串和字节对象转换为False,True否则。
该None对象皈依False为好。
所有其他对象评估为True。
注意:用户定义的类可以提供一个.__bool__()dunder 方法来定义其类实例的真实性。
如果要测试容器或字符串是否为非空,则只需在布尔上下文中提供该对象即可。这被认为是一种Pythonic方法。
查看以下不同的方法来检查非空字符串:
>>>
>>> s = "some string" >>> if s != "": # Comparing two strings ... print('s != ""') ... s != "" >>> if len(s) != 0: # Asking for the string length ... print("len(s) != 0") ... len(s) != 0 >>> if len(s): # Close, but no cigar ... print("len(s)") ... len(s) >>> if s: # Pythonic code! ... print("s") ... s
在最后一个示例中,您只需在布尔上下文中提供字符串。如果字符串不为空,则它的计算结果为真。
注意:以上并不意味着依赖于bool所有类型的隐式转换是Pythonic 。下面的部分None更详细地解决了这个问题。
如果您想了解更多关于最典型的 Python 构造的信息,可以遵循编写更多 Pythonic 代码学习路径。
在 Python 中,您将使用条件运算符 ( )用 Java 编写的条件表达式编码为带有关键字和的表达式:? :ifelse
考虑 Python 中此类表达式的示例:
>>>
>>> for n in range(3): ... word = "item" if n == 1 else "items" ... print(f"Amount: {n:d} {word}") ... Amount: 0 items Amount: 1 item Amount: 2 items
REPL"item"仅在n等于时输出1。在所有其他情况下,REPL 输出"items".
没有任何
在 Python 中,None是一个单例对象,您可以使用它来识别类似空值的值。在 Java 中,您会null出于类似目的使用文字。
NonePython 中最常使用的是作为函数或方法定义中的默认参数值。此外,不返回任何值的函数或方法实际上None隐式返回对象。
一般来说,当您依赖于布尔上下文中的隐式转换时,它被视为代码异味,None因为您可能会为其他类型的对象编写意外行为,而这些对象碰巧返回假值。
因此,如果您想测试一个对象是否真的是该None对象,那么您应该明确地这样做。因为只有一个None对象,您可以使用对象标识运算符is或相反的运算符来实现is not:
>>>
>>> some_value = "All" or None >>> if some_value is None: ... print(f"is None: {some_value}") >>> if some_value is not None: ... print(f"is not None: {some_value}") ... is not None: All
请记住,not这里的单词是is not运算符不可分割的一部分,它与逻辑not运算符显然不同。在此示例中,字符串"All"在布尔上下文中具有一个真值。您可能还记得or运算符有这种短路行为,并且只要知道结果就立即返回最后一个表达式,"All"在这种情况下。
更多容器数据类型
Java 通过其集合框架提供其标准容器类型。
Python 采用了不同的方法。它提供了您在本节前面探索的基本容器类型作为内置类型,然后 Python 的标准库通过collections模块提供了更多容器数据类型。您可以通过该collections模块访问许多有用的容器类型示例:
namedtuple 提供元组,您还可以在其中通过字段名称访问元素。
deque 提供双端队列,在集合的两端快速追加和删除。
ChainMap 允许您将多个映射对象折叠到映射上的单个视图中。
Counter 提供用于计算可散列对象的映射。
defaultdict 提供调用工厂函数来提供缺失值的映射。
这些数据容器类型仅在纯 Python 中实现。
至此,您已为理解 Java 与 Python 的特性、语法和数据类型之间的异同奠定了良好的基础。现在是时候退后一步,探索可用的 Python 库和框架,并找出它们对特定用例的适用性。
有哪些特定用途的资源?
您可以在许多使用领域使用 Python。您将在下面找到其中一些领域,以及它们最有用和最流行的相关 Python 库或框架:
命令行脚本: argparse提供创建命令行参数解析器的功能。
网络框架:
在开发完整且可能复杂的网站时,Django提供了更多的收缩包装方法。它包括定义模型的能力,提供自己的 ORM 解决方案,并提供完整的管理功能。您可以添加其他插件以进一步扩展管理。
Flask 将自己标榜为一个专注于做好一件事的微框架,即服务于 Web 请求。您可以将此核心功能与您自己选择的其他现有组件相结合,例如 ORM 和表单验证。许多扩展,称为 Flask 插件,可用于为您很好地集成这些组件。
Requests使得发送 HTTP 请求非常方便。
数据建模与分析: pandas基于NumPy,是一款快速、强大、灵活、直接的开源数据分析与操作工具。有些人将熊猫称为“类固醇的可编程电子表格”。
机器学习: TensorFlow,Keras和PyTorch在机器学习方面的几个流行的框架。
SQL 工具包和对象关系映射器 (ORM): SQLAlchemy是一个非常流行的 Python SQL 工具包和 ORM 框架。
工作负载分配: Celery是一个分布式任务队列系统。
Python 还有一些值得注意的与质量保证相关的工具:
pytest是标准unittest库的绝佳替代品。
行为是一种流行的行为驱动开发(BDD)工具。您可以将它与PyHamcrest结合使用以进行更具表现力的断言检查。
Flake8是一个编码风格指南检查器。
Pylint是一种工具,用于检查 Python 代码中的错误并识别代码异味和编码标准偏差。
Black是不妥协、固执己见、难以配置的代码重新格式化程序。尽管这听起来很糟糕,但在现实生活中,它是任何大型软件项目的绝佳工具。
mypy是使用最广泛的静态类型检查器。
Bandit发现常见的安全问题。
安全检查您安装的依赖项是否存在已知的安全漏洞。
tox是一种命令行工具,可帮助运行在一个命令中为您的项目定义的自动化测试和 QA 工具检查以及多个 Python 版本和依赖项配置。
上面的列表只是众多可用包和框架中的一小部分。您可以浏览和搜索 Python 包索引 (PyPI) 以找到您正在寻找的特殊包。
Python 何时会比 Java 更有用,为什么?
通常,您希望为一个用例选择一种编程语言,为另一个用例选择一种不同的编程语言。在比较 Java 与 Python 时,您应该考虑以下几个方面:
Java 和 Python 都成功地用于世界上最大的 Web 应用程序中。
您还可以使用 Python 编写 shell 工具。
Python 优雅的语法、代码可读性、广泛的库和大量的外部包允许快速开发。您可能只需要不到一半的代码行数即可实现与在 Java 中相同的功能。
因为标准 Python 不需要编译或链接步骤,所以当您更新代码时,您会立即看到结果。这进一步加快了开发周期。
在大多数情况下,对于一般应用程序,标准 Java 执行速度高于 Python。
您可以相对轻松地使用 C 或 C++扩展Python。这在一定程度上缓解了执行速度的差异。
对于某些用途,例如数据建模、分析、机器学习和人工智能,执行速度确实很重要。为此功能创建的流行的第三方包是用编译为本机代码的编程语言定义的。对于这些领域,Python 似乎是最合乎逻辑的选择。
结论
在本教程中,您熟悉了 Python,并清楚地了解了这种编程语言的特性。您已经探索了 Java 和 Python 之间的异同。
您现在已经有了一些快速入门 Python 的经验。您也有一个很好的基础来了解应用 Python 对哪些情况和哪些问题域有用,以及您接下来可以查看哪些有用资源的概述。
在本教程中,您了解了:
Python 编程语言的语法
Python中相当多的标准数据类型
Python与 Java 的不同之处
Java和Python有哪些相似之处
在哪里可以找到 Python文档和特定主题的教程
如何开始使用 Python
如何使用 Python REPL查看即时结果
一些最喜欢的框架和库
也许您确定将来会更多地使用 Python,或者您仍在决定是否更深入地研究该语言。无论哪种方式,通过上面总结的信息,您都可以很好地探索 Python 和本教程中介绍的一些框架。
其他资源
当您准备好了解有关 Python 及其软件包的更多信息时,网络上有大量可用资源:
您可以找到涵盖许多有关Real Python 的主题的书面教程、视频课程、测验和学习路径。
外部 Python 实用程序、库和框架通常提供良好的文档。
PyVideo.org提供了大量免费提供的来自世界各地 Python 相关会议的演示文稿的索引集合。
最后但同样重要的是,官方Python 文档对 Python 编程语言、其标准库和生态系统的所有信息都保持了高标准的准确和完整的信息。
现在您已经了解 Python 实际上是一种什么样的编程语言,您希望对它充满热情,并考虑将它用于您的下一个项目,无论是小项目还是大项目。快乐的python!
Java Python
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。