甲壳虫|python到底是强类型语言,仍是弱类型语言?


甲壳虫|python到底是强类型语言,仍是弱类型语言?
本文插图

作者:豌豆花下猫
来源:Python猫
上一篇文章分析了 为什么 python 没有 void 类型 的话题 , 在文章发布后 , 有读者跟我讨论起了另一个关于类型的题目 , 但是 , 我们很快就泛起了重大不合 。
我们主要的不合就在于:Python 到底是不是强类型语言?我以为是 , 而他以为不是 。 他写了一篇很长的文章《谁告诉的你们Python是强类型语言!站出来 , 保证不打你!》 , 专门重申了他的观点 , 但可惜错漏百出 。
我曾有设法要写写关于 python 类型的题目 , 现在借着这个机会 , 就来系统地梳理一下吧 。
(PS:在我写作进行到差不多一半的时候 , 微信读者群里刚好也讨论到“强弱类型”的话题!在与大家讨论时 , 我的一些设法得到了验证 , 同时我也学到了许多新知识 , 所以本文的部门内容有群友们的功劳 , 特此鸣谢!)
1、消息类型与强弱类型
许多读者应该都认识动态类型与静态类型 , 但是许多人也会把它们跟强弱类型混为一谈 , 所以我们有必要先作一下概念上的澄清 。
这两组类型都是针对于编程语言而言的 , 但关注的核心题目不同 。
对于“消息类型”概念 , 它的核心题目是“什么时候知道一个变量是哪种类型”?
一般而言 , 在编译期就确定变量类型的是静态类型语言 , 在运行期才确定变量类型的则是动态类型语言 。
例如 , 某些语言中定义函数“int func(int a){…}” , 在编译时就能确定知道它的参数和返回值是 int 类型 , 所以是静态类型;而典型如 Python , 定义函数时写“def func(a):…” , 并不知道参数和返回值的类型 , 只有到运行时调用函数 , 才终极确定参数和返回值的类型 , 所以是动态类型
对于“强弱类型”概念 , 它的核心题目是“不同类型的变量是否答应隐式转化”?
一般而言 , 编译器有很少(公道)隐式类型转化的是强类型语言 , 有较多(过分)隐式类型转化的是弱类型语言 。
例如 , Javascript 中的 "1000"+1会得到字符串“10001” , 而 "1000"-1则会得到数字 999 , 也就是说 , 编译器根据使用场合 , 对两种不同类型的对象分别做了隐式的类型转化 , 但是相似的写法 , 在强类型语言中则会报类型犯错 。 (数字与字符串的转化属于过分的转化 , 下文会再提到一些公道的转化 。 )
按照以上的定义 , 有人将常见的编程语言画了一张分类图:
甲壳虫|python到底是强类型语言,仍是弱类型语言?
本文插图

按强弱类型维度划分 , 可以归纳出:
强类型:Java、C#、Python、Ruby、Erlang(再加GO、Rust)……弱类型:C、C++、Javascript、Perl、PHP、VB……2、过去的强弱类型概念
消息类型的概念基本上被大家所认可 , 然而 , 强弱类型的概念在问答社区、技术论坛和学术讨论上却有许多的争议 。 此处就不作罗列了 。
为什么会有那么多争议呢?
最主要的原因之一是有人把它与消息类型混用了 。
最显著的一个例子就是 Guido van Rossum 在 2003 年参加的一个访谈 , 它的话题刚好是关于强弱类型的(Strong versus Weak Typing):
甲壳虫|python到底是强类型语言,仍是弱类型语言?
本文插图

但是 , 他们谈论的显著只是消息类型的区别 。
访谈中还引述了 Java 之父 James Gosling 的话 , 从他的表述中也能看出 , 他说的“强弱类型”实在也是消息类型的区分 。
另外还有一个经典的例子 , C 语言之父 Dennis Ritchie 曾经说 C 语言是一种“强类型但是弱检查”的语言 。 假如对照成前文的定义 , 那他实在指的是“静态类型弱类型” 。


推荐阅读