Hi,您好,欢迎来到西安盛图软件科技有限公司!

那些被忽视的 Python 核心功能...

发布时间:2023-08-09 13:40:14

最实用、最简单、最优美...近些年,大家学习 Python 的热潮从未消退;无论是数据分析还是科学计算都少不了 Python 的身影。

Python 也没有让人失望,Java 用 100 行代码写出的程序,用 Python 十行就能搞定!


当你要说 Hello World 时,C 语言、Java、Python 分别是这样的:

640.png

一目了然,Python 只需一行!


虽然 Python 非常容易学习,但是许多实践者只触及到它的表面,而忽视了深入研究这门语言更高级、更强大的方面,而正是这些被忽视的方面使它如此独特和强大。  ——节选自《Fluent Python》

640.png

如果你的目标是成为一名经验丰富的 Python 程序员,你一定想了解的更多。因此,让我们共同了解下你没听过的 Python 核心功能,先从最简单的排列与组合开始...

功能一:排列与组合

你可以组合不同的 for 循环,输出排列、组合和笛卡尔积等。

1.排列

举个例子:当你在排列函数中输入{[1,2,3],2}时,会输出如下结果:

640.png

2.组合

当你在组合函数中输入(‘ABC’,2)时,输出的排列如下:

640.png

3.卡尔积

笛卡尔积是数学中的一种运算,用于求两个集合中所有可能的有序对。

当我们用笛卡尔积计算 Python 时,结果是这样的:

640.png

功能二:可变的参数默认值

现在,开始增加难度...

当你每次调用 fib_memo 函数却不为 memo 参数赋值时,它将自动使用定义该函数时的原始值,公式和代码如下:

640.png

由于在 Python 中,默认参数是可变的,你也可以像在“for 循环”中一样在单个脚本中多次执行函数,每次执行都能自动增加要计算的斐波那契数,而不会超过“最大递归深度”限制,因为 memo 可持续扩展。


*重要提示:

请记住,尽管可变的默认参数(如上所述)可以减少代码,但它可能产生难以解决的 bug。有些人将其判定为“陷阱”,而不是功能。因此,你仍需要坚持 Python 中所透露出的禅意:显式优于隐式。

就像 Hacker news 中指出的那样:if n not in memo 比 if not n in memo 更容易读取,但是二者输出结果相同。

功能三:海象运算符

下面,再来讲讲比较有趣的“海象运算符”...

“海象运算符”是在 Python 3.8 版本中引入的赋值表达式运算符,用于在表达式中进行赋值操作,其符号为“:=”。这个符号有点像海象的眼睛和獠牙(因此被称为「海象运算符」)。


它可以被翻译成英文“whale calculus”,是一种基于单词语法规则的特殊运算符,用于定义表达式和一系列操作步骤的语言建模方式。

640.png

显然,用 Python,赋值和检查返回值是否包含真值变得更容易了:

640.png

功能四:单星号(*)和双星号(**)

当调用 sum_numbers 函数而不解包 my_numbers 时,会引发"TypeError",因为该函数需要输入两个单独的参数才能输出结果。

但是,通过使用(*),我们可以解压缩 my_numbers 函数中的值,并将它们作为单独的参数进行传递,从而产生正确的输出。

这种解包技术不仅适用于元组和列表,也适用于字典。


当关键字作为参数时,我们可以使用双星号(**),以如下代码为例:

640.png

除解压缩序列以将其作为参数传递给函数外,你还可以使用它来创建新序列,例如:

640.png

在此过程中,原始数字列表不受影响,并且你还将拥有一个 new_list_numbers 变量,它包括相同列表的副本。

640.png

功能五:any and any

any 和 all 都是 python 中的内置函数,它们对可迭代对象(如,列表、元组或集合)进行操作,并根据可迭代对象中的元素以 Boolean 运算的形式返回,语句如下:

640.png


你可以将 any 和 all 函数与列表推导式结合使用,列表推导式返回一个可迭代对象并将其作为参数传递给 all 函数:

640.png

或任意函数:

640.png


下表列出可迭代对象中用 any 和 all 函数赋值的输出差异:

640.png

功能六:交换变量

用 Python,你可以将参数打包((=)号右边)和解包((=)号左边)结合起来,并利用此功能交换变量:

640.png

功能七:str vs repr

在字符串处理方面,Python 中的 str()和 repr()有所不同。str()将值转化为前端样式文本,repr()是后端底层代码。

下图是一个很好的例子:

640.png



如你所见,repr()简单将时间排列为字符串后输出;如果你想确定当前变量是否包含字符串或时间对象,无法借此识别。

str()提供了变量持有的实际对象信息,这些信息在调试过程中非常有价值。

功能八:扩展的迭代解包

迭代解包可应用到任何可迭代对象上,唯一的硬性要求是:被迭代对象中的元素数量必须与接受这些元素的元组空档数一致,也可以使用星号 * 表示忽略多余的元素。

这种方式的优点在于:更好赋值、更好获取迭代对象中的某个值(一般的迭代对象分为:元组,列表,字典,字符串等)。

如果你想获得序列的第一个和最后一个值,需要输入如下代码:

640.png

更换输入和输出语句后同样可行...

640.png


其它组合也同样适用...

功能九:多个上下文管理器

通常,我们习惯一次性使用一个上下文管理器,比如,当你打开一个程序文件,需要输入如下代码:

640.png

但是,在 Python 中,用一行语句就能打开多个文件。如果你想将行写入其它文件,用 Python 语句就很容易实现,例如:

640.png

功能十:调试程序

为达到调试目的,我们可以在文件中输出大量变量或可以简单使用 Python 调试器(pdb),它可以帮我们设置断点:

640.png



程序将在断点处停止,你可以在该断点处获取任何变量以检查其值或该特定断点是否存在。当程序遇到断点时,可使用如下几个命令: