小米note3,简练 or 缺点?Python 内置函数大揭秘!-优德88官方

admin4个月前242浏览量

来历:CSDN衔接:https://blog.csdn.net/csdnnews/article/details/89702196



作者 | 豌豆花下猫

责编 | 胡巍巍

内置函数是 Python 的一大特征,用极简的语法完成许多常用的操作。

它们预先界说在内置命名空间中,开箱即用、所见即所得。Python 被公认是一种新手友爱型的言语,这种说法可以建立,内置函数在其间起到了极要害的效果。

举个比如,求字符串 x 的长度,Python 的写法是 len(x) ,并且这种写法对列表、元组和字典等目标也相同适用,只需要传入对应的参数即可。len() 函数是共用的。

这是一种极简哲学的表现:Simple is better than complex。

但是,有些言语并不是这样,例如在 Java 中,字符串类有一个求长度的办法,其它类也有自己的求长度的办法,它们无法共用。每次运用时,经过类或实例来调用。

相同是求字符串长度,Python 的写法:

saying = "Hello world!"
print(len(saying))
# 成果:12

而在 Java 中,写法或许如下(简化起见):

String saying = "Hello world!";
System.out.println(saying.length());
// 成果:12

Python 选用的是一种前缀表达式 ,而 Java 选用的则是后缀表达式 。

除了求长度,Python 的某些内置函数也能在 Java 中找到对应的表达。例如,数值型字符串 s 转化为整型数字,Python 可以用 int(s) 函数,而 Java 可以用 Integer.parseInt(s);整型数字转化为字符串,Python 可以用 str(i),而 Java 也有String.valueOf(i)。

Python 的内置函数不与特定的类绑定,它们是一级目标。而 Java 的“函数”则无法脱离类而存在,它们仅仅附属品。

从直观视点来看,Python 的表达似乎是更优的。但是,它们并不具有可比性 ,由于这是两套言语体系,各有共同的领域布景,并不能轻易地化约。

就比如是,不能由于拉丁字母笔画简略,就说它优于汉字,由于在表意时,字母(表音文字)是远逊于汉字(表意文字)的。

相同,日本借用了汉字的偏旁部首而造出来的文字,尽管更省翰墨,但是也彻底丧失了意蕴。

以此类比,Python 的内置函数虽有简洁之美,但却丢掉了某些表意功用。有些人在质疑/打击 Python 的时分,也喜爱拿这点说事,以为这是 Python 的规划缺点。

这就引出本文最想评论的一个问题来:为什么 Python 要规划成 len(x) 这种前缀表达,而不是 x.len() 这样的后缀表达呢?

事实上,后缀规划也是可行的,以 Python 中列表的两个办法为例:

mylist = [2, 1, 3, 5, 4]
mylist.sort()
print(mylist) # [1, 2, 3, 4, 5]
mylist.reverse()
print(mylist) # [5, 4, 3, 2, 1]

它们都是经过列表目标来调用,并不是随便从内置命名空间中拿来的。语义表达得也很清楚,便是对 mylist 做排序和反转。

恰恰那么巧,它们还有两个同父异母的兄弟 sorted() 与 reversed(),这俩是前缀表达型。

mylist = [2, 1, 3, 5, 4]
sort_list = sorted(mylist)
print(sort_list) # [1, 2, 3, 4, 5]
reverse_list = reversed(mylist)
print(list(reverse_list)) # [4, 5, 3, 1, 2]

不同的写法,都在做同一件事(不考虑它们的副效果)。因而,后缀语法并非不可行,之所以不用,那肯定是故意的规划。

回到前面的问题:为什么是 len(x) ,而非 x.len(x),这源于 Python 的什么规划思维呢?

Python 之父 Guido van Rossum 从前解说过这个问题(链接见文末),有两个原因:

  • 关于某些操作,前缀符比后缀更好读——前缀(和中缀)表明法在数学中有着悠长的前史,其视觉效果有助于数学家思考问题。咱们可以简略地把公式 x*(a + b) 重写成 x*a + x*b ,但相同的事,以原生的面向目标的办法完成,就比较蠢笨。
  • 当读到 len(x) 时,我就 知道 这是在求某目标的长度。它告诉我了两点:返回值是一个整数,参数是某种容器。但当读到 x.len() 时,我有必要事前知道某种容器 x,它完成了一个接口,或许承继了一个具有规范 len() 办法的类。咱们经常会目击到这种紊乱:一个类并没有完成映射(mapping)接口,却具有 get() 或 keys() 办法,或许某些非文件目标,却具有一个 write() 办法。

解说完这两个原因之后,Guido 还总结成一句话说:“I see 'len' as a built-in operation ”。这现已不仅是在说 len() 更可读易懂了,而彻底是在提高 len() 的位置。

这就比如说,分数 ½ 中的横线是数学中的一个“内置”表达式,并不需要再完成什么接口之类的,它本身现已表明晰“某数除以某数 ”的意思。

不同类型的数(整数、浮点数、有理数、无理数…...)共用同一个操作符,不用为每类数据完成一种求分数的操作。

高雅易懂是 Python 奉行的规划哲学 ,len() 函数的前缀表达办法是最好的表现。

我想起在《超强汇总:学习Python列表,只需这篇文章就够了》这篇文章中,曾引述过 Guido 对“为什么索引从 0 开端 ”的解说。其最重要的原因,也正是 0-based 索引最高雅易懂。

让咱们来先看看切片的用法。或许最常见的用法,便是“取前 n 位元素”或“从第i 位索引起,取后 n 位元素”(前一种用法,实际上是 i == 开始位的特别用法)。假如这两种用法完成时可以不在表达式中呈现丑陋的 +1 或 -1,那将会十分的高雅。运用 0-based 的索引办法、半开区间切片和缺省匹配区间的话(Python终究选用这种办法),上面两种景象的切片语法就变得十分美丽:a[:n] 和 a[i:i+n],前者是 a[0:n] 的缩略写法。

所以,咱们能说 len(x) 打败 x.len() ,支撑它的是一种化繁为简、朴实却深邃的规划思维。

面向目标的编程言语自发明时起,就想模仿咱们日子于其间的实际国际。但是什么类啊、接口啊、目标啊、以及它们的办法啊,这些玩意的毒,有时分遮盖了咱们去看见国际实质的眼睛。

桌子类有桌子类的求长度办法,椅子类有椅子类的求长度办法,无穷无尽,可实际真是如此么?

求长度的办法就不能是一种独立存在的目标么?它之所以存在,是由于有“目标”存在,而不是由于有某个类才存在啊。

所以,我想说,len(x) 打败 x.len(),这还表现了 Python 对国际实质的洞悉 。

求某个目标的长度,这种操作独立于目标之外而存在,并不是该目标内部一切的一种特点或功用。从这个视点了解,咱们可以理解,为什么 Python 要规划出内置函数? 内置函数其实是对国际实质的一种捕捉。

这些见微知著的发现,满足使咱们爱上这门言语了。人生苦短,我用 Python。