作者:豌豆花下猫

来源:Python猫

之前我们对比了两种创建列表的方法,即字面量用法 [] 与内置类型用法 list(),进而分析出它们在运行速度上的差异。

在分析为什么 list() 会更慢的时候,文中说到它需要经过名称查找与函数调用两个步骤,那么,这就引出了一个新的问题:list() 不是内置类型么,为什么它不能直接就调用创建列表的逻辑呢?也就是说,为什么解释器必须经过名称查找,才能“认识”到该做什么呢?

其实原因很简单:内置函数/内置类型的名称并不是关键字,它们只是解释器内置的一种便捷功能,方便开发者开箱即用而已。

PS:内置函数 built-in function 和内置类型 built-in type 很相似,但 list() 实际是一种内置类型而不是内置函数。我曾对这两种易混淆的概念做过辨析,请查看这篇文章。为了方便理解与表述,以下统称为内置函数。

1、内置函数的查找优先级最低

内置函数的名称并不属于关键字,它们是可以被重新赋值的。

比如下面这个例子:

# 正常调用内置函数list(range(3)) # 结果:[0, 1, 2]# 定义任意函数,然后赋值给 listdef test(n): print("Hello World!")list = testlist(range(3)) # 结果:Hello World!

在这个例子中,我们将自定义的 test 赋值给了 list,程序并没有报错。这个例子甚至还可以改成直接定义新的同名函数,即"def list(): …"。

这说明了 list 并不是 Python 限定的关键字/保留字。

查看官方文档,可以发现 Python3.9 有35个关键字,明细如下:

如果我们将上例的 test 赋值给任意一个关键字,例如"pass=test",就会报错:SyntaxError: invalid syntax。

由此,我们可以从这个角度看出内置函数并不是万能的:它们的名称并不像关键字那般稳固不变,虽然它们处在系统内置作用域里,但是却可以被用户局部作用域的对象所轻松拦截掉!

因为解释器查找名称的顺序是“局部作用域->全局作用域->内置作用域”,因此内置函数其实是处在最低优先级。

对于新手来说,这有一定的可能会发生意想不到的情况(内置函数有 69 个,要全记住是有难度的)。

那么,为什么python 不把所有内置函数的名称都设为不可复写的关键字呢?

一方面原因是它想控制关键字的数量,另一方面可能是想留给用户更多的自由。内置函数只是解释器的推荐实现而已,开发者可以根据需要,实现出与内置函数同名的函数。

不过,这样的场景极少,而且开发者一般会定义成不同名的函数,以 Python 标准库为例,ast模块有 literal_eval() 函数(对标 eval() 内置函数)、pprint 模块有 pprint() 函数(对标 print() 内置函数)、以及itertools模块有 zip_longest() 函数(对标 zip() 内置函数)……

2、内置函数可能不是最快的

由于内置函数的名称并非保留的关键字,以及它处于名称查找的末位顺序,所以内置函数有可能不是最快的。

上篇文章展示了 [] 比 list() 快 2~3 倍的事实,其实这还可以推广到 str()、tuple()、set()、dict() 等等内置类型中,都是字面量用法稍稍快于内置类型用法。

对于这些内置类型,当我们调用 xxx() 时,可以简单理解成正在做类的实例化。在面向对象语言中,类先实例化再使用,这是再正常不过的。

但是,这样的做法有时也显得繁琐。为了方便使用,python 给一些常用的内置类型提供了字面量表示法,也就是""、[]、()、{} 等等,表示字符串、列表、元组和字典等数据类型。

一般而言,所有编程语言都必须有一些字面量表示,但基本都局限在数字类型、字符串、布尔类型以及 null 之类的基础类型。

Python 中还增加了几种数据结构类型的字面量,所以是更为方便的,同时这也解释了为什么内置函数可能不是最快的。

一般而言,同样的完备功能,内置函数总是比我们自定义的函数要快,因为解释器可以做一些底层的优化,例如 len() 内置函数肯定比用户定义的 x.len() 函数快。

有些人据此形成了“内置函数总是更快”的认识误区。

解释器内置函数相对于用户定义函数,前者接近于走后门;而字面量表示法相对于内置函数,前者是在走更快的后门。

也就是说,在有字面量表示法的情况下,某些内置函数/内置类型并不是最快的!

小结

诚然,python 本身并不是万能的,那它的任何语法构成部分(内置函数/类型),就更不是万能的了。但是,一般我们会认为内置函数/类型总归是“高人一等”的,是受到诸多特殊优待的,显得像是“万能的”。

本文从“list() 竟然会败给 []”破题,从两个角度揭示了内置函数其实存在着某种不足:内置函数的名称并不是关键字,而内置作用域位于名称查找的最低优先级,因此在调用时,某些内置函数/类型的执行速度就明显慢于它们对应的字面量表示法。

以下不是python内置函数的是_为什么说python内置函数并不是万能的?相关推荐

  1. python自带的函数有哪些_为什么说 Python 内置函数并不是万能的?

    在Python猫的上一篇文章中,我们对比了两种创建列表的方法,即字面量用法 [] 与内置类型用法 list(),进而分析出它们在运行速度上的差异. 在分析为什么 list() 会更慢的时候,文中说到它 ...

  2. python内置函数源码_如何查看python内置函数源码

    在用Python进行各种分析的时候,我们会用到各种各样的函数,比如,我们用SQL时,经常使用join.max等各种函数,那么想看Python是否有这个函数,这个时候可能大部分人会百度,那么如何不使用百 ...

  3. python中用什么函数读取字符串_如何在Python中获得函数名作为字符串?

    在Python中,如何在不调用函数的情况下以字符串的形式获得函数名? 1 2 3 4def my_function(): pass print get_function_name_as_string( ...

  4. python中home定义是什么_第48p,什么是函数?,Python中函数的定义

    原标题:第48p,什么是函数?,Python中函数的定义 大家好,我是 杨数 Tos ,这是<从 零 基础到大神>系列课程的第 48 篇文章 ,第三阶段的课程 : Python进阶知识:详 ...

  5. python中匿名函数的作用_什么是Python中的匿名函数

    匿名函数 lambda x , y : x+y 1.匿名的目的就是要没有名字,给匿名函数赋给一个名字是没有意义的. 2.匿名函数的参数规则.作用域关系与有名函数是一样的. 3.匿名函数的函数体通常应该 ...

  6. python中什么是关键字参数_如何使用python语言中函数的关键字参数的用法

    一般情况下,在调用函数时,使用的是位置参数,即是按照参数的位置来传值:关键字参数是按照定义函数传入的参数名称来传值的.那么,关键字参数怎么使用? 工具/原料 python pycharm 截图工具 W ...

  7. python嵌套类(内部类相互调用)_核心解密Python函数在(类与函数之间)和(类与类之间)互相调用...

    image.png 一.类与函数之间 首先来看一个函数间的调用 类方法: #实现类中函数之间互相调用 #下面一个学生的简单自我介绍为例子 __metaclass__=type #自由的.动态的修改/增 ...

  8. python input函数详解_对Python3中的input函数详解

    下面介绍python3中的input函数及其在python2及pyhton3中的不同. python3中的ininput函数,首先利用help(input)函数查看函数信息: 以上信息说明input函 ...

  9. python画函数图像网格_如何基于Python Matplotlib实现网格动画

    -1- 如果你对本文的代码感兴趣,可以去 Github (文末提供)里查看.第一次运行的时候会报一个错误(还没找到解决办法),不过只要再运行一次就正常了. 这篇文章虽然不是篇典型的数据科学类文章,不过 ...

最新文章

  1. matepad和鸿蒙,爆料称华为MatePad 2系列平板有三个版本:预装鸿蒙OS
  2. 正则表达式实现将html文本转换为纯文本格式(将html字符串转换为纯文本方法)
  3. [转]Vi 教程(Unix行编辑器)
  4. rxjava背压_如何形象地描述RxJava中的背压和流控机制?
  5. BZOJ1725 牧场的安排
  6. Windows10家庭版安装Docker Desktop(非Docker Toolbox)
  7. MATLAB安装工具箱
  8. oc-Foundation框架-结构体
  9. pkcs1与pkcs8格式RSA私钥互相转换
  10. 拓扑排序:编译依赖问题
  11. 自动驾驶各大传感器介绍-硬件篇
  12. 怎样将生成的pdf文件转为eps文件
  13. matlab改变图片尺寸及像素与尺寸的转换
  14. 分贝测试软件哪个好 家庭影院,家庭影院隔音怎么做效果最好 这7个解决方案你一定要知道...
  15. python画史迪仔_手把手教你如何使用Python来生成马赛克画!
  16. 破解人脸识别被判七年!打击黑产,鼓励人脸识别技术健康发展
  17. 什么是僵尸进程(Zombie Processes)
  18. webpack合成sprite图
  19. 云计算赛项-私有云skywalking服务部署与应用
  20. 冷链食品追溯迫在眉睫,爱码物联3步助力冷链溯源

热门文章

  1. HDU 4404 Worms(多边形和圆相交)
  2. 两种排序方法(直接判断)
  3. ambari下 hive metastore 启动失败
  4. 视觉SLAM算法框架解析(1) PTAM
  5. 循环不变式(loop invariant)
  6. kalman filter using python
  7. Ubuntu 20.04 上搭建 LEMP/LAMP 环境运行 WordPress
  8. 定期删除30天以前的elasticsearch的日志
  9. Dell R720服务器安装Ubuntu 16.04 Server 版步骤
  10. php asort,PHP asort() 函数