最近和网友讨论Python到底是强类型,还是弱类型的问题。我还特意写了篇文章《谁告诉的你们Python是强类型语言!站出来,保证不打你!》的文章来论述这个问题。有网友写了另外一篇文章《Python到底是强类型语言,还是弱类型语言?》来驳斥了我的观点。这篇文章我仔细阅读了一下。先不讨论文章的观点是否正确。我先来给出一些文章的片段。

上面截取了《Python到底是强类型语言,还是弱类型语言?》的5段内容。其实这5段内容从文字表达和逻辑上并没有什么问题。其基本中心思想就是:隐式类型转换是判断语言强弱类型的主要标准之一。但并不能认为强类型语言就没有隐式类型转换,部分强类型语言很可能有一些合理的隐式类型转换。

先不管这个结论正确与否,先看第1段、第4段和第5段用红框括起来的内容,这里用了一些词:非常多、非常复杂、非常过分、合理、很少。当然,这些词大家都理解是什么意思,都是一些强调程度的形容词。不过将这些词用在计算机科学中就不太好了。请作者解释下,啥叫非常多、非常复杂、非常过分、合理、很少。要达到什么程度才算是非常多和复杂呢?恐怕100个人就会有100个看法。你说JavaScript用了非常过分的方式进行类型转换,但我认为不过分,这些都只是一种语言应该做的正常行为。例如,"1000" - 1,这个不应该将"1000"转换为1000,然后再与1相减吗? 这才符合人们的认知啊。Java之所以不支持,是因为Java太Low,而不是js太过分。

另外,这个非常多,非常过分的尺度也不太好掌握,例如,go、java和javascript来说。go并不支持string + int的形式,java支持string+int的形式(按作者的意思,是合理的隐式类型转换),但java不支持string - int的形式(按作者意思,是不合理的隐式类型转换),而javascript都支持。java的灵活度正好介于go和javascript之间。那你是说java属于过分,还是不过分呢? 凭啥认为“+”就不过分,“-”就过分呢?

而且作者还用我的Python例子:String * int来举例,没错,在这个例子中,确实没做类型做换。不过这个只是我举的一个情形而已,说的是乘号(*)。那如果我自己设计一种编程语言(假设叫marvel语言),其他特性都与Java相同,唯独支持特定形式的String * String,例如,如果用"abcdefg" * “10”,marvel语言就会认为左侧是字符串,右侧是字符串形式的整数,我完全可以将"10"转换为10,然后就相当于Python的"abcdefg" * 10了。当然,这种转换是有限制的,只限于值。变量、函数不会转换,例如,a * b形式,即使a = "abcdefg" ; b = "10",也不会自动转换。 还有就是如果两个操作数都是数值类型的字符串也不会转换,如"1000" * "10",这样会产生歧义,到底是将"1000"转换为1000,还是将"10"转换为10呢?当然,也可以做另外一种语义,就是将"1000"和"10"都进行转换,就变成1000 * 10 = 10000了。这些都是隐式类型转换。那你说这种转换是否合理、是否过分呢?我说他不过分,并且是合理的。因为如果从json或xml文件中读取的值,全部都是字符串类型的。如果一开始做的json to object的映射为了通用,都使用了字符串,那么这么做就是合理的。否则需要自己做显式类型转换了。

还有就是,假设有大多数人认为的1000处不合理隐式类型转换的语法。而一种编程语言只有1个隐式类型转换的地方采用了这种不合理的转换,其他的隐式类型转换都被认为合理的!难道就因为这种编程语言只有这1个地方大多数人认为是不合理的,就被认为是弱类型语言?简直是笑话!

注意,这是重点:

在维基百科上也有关于强弱类型的解释,链接如下:

https://en.wikipedia.org/wiki/Strong_and_weak_typing

前面的介绍我摘录了一段:

In computer programming, programming languages are often colloquially classified as to whether the language's type system makes it strongly typed or weakly typed (loosely typed). However, there is no precise technical definition of what the terms mean and different authors disagree about the implied meaning of the terms and the relative rankings of the "strength" of the type systems of mainstream programming languages.

Generally, a strongly typed language has stricter typing rules at compile time, which implies that errors and exceptions are more likely to happen during compilation. Dynamically typed languages (where type checking happens at run time) can also be strongly typed. Most of these rules affect variable assignment, return values and function calling.

A weakly typed language has looser typing rules and may produce unpredictable results or may perform implicit type conversion at runtime.

下面我给翻译一下:

》》》》》》

在计算机编程中,编程语言通常会按语言的类型系统进行分类,将语言分为强类型语言或弱类型(宽松类型)语言。 但是,对于术语的含义没有精确的技术定义,并且不同的作者不同意术语的隐含含义和主流编程语言类型系统“强度”的相对排名。

通常,强类型语言在编译时具有更严格的类型规则,这意味着在编译过程中更容易发生错误和异常。 动态类型语言(在运行时进行类型检查)也可以强类型化。 这些规则大多数会影响变量分配,返回值和函数调用。

弱类型语言具有较宽松的类型规则,可能会产生不可预测的结果,或者可能在运行时执行隐式类型转换。

《《《《《《

从这段文字可以看出,其实强弱类型到现在仍然是存在争议的。并没有精确的技术定义。就相当于我说一个女孩是美女,这个“美”只是一个形容词。其实美女并没有精确的标准,不同时代、不同民族、不同宗教、不同年龄的人对审美是不同的,所以用美女帅哥形容女性和男性是没问题的,但并不能用美女和帅哥对人进行分类啊,因为这个没有精确标准的。不同人的分类肯定是不同的。语言的类型强弱也是一个形容词。例如,Python对类型的处理比JavaScript严格,这是没问题的。但还上升不到学术的程度。强弱类型与静态和动态完全不是一个层次的概念,不要混为一谈。

另外,维基百科并不是真理,这些也是人编写的。

最后说一下我的第1个结论:不管我们的观点如何,描述科学的结论,需要用确定的词语,是就是,不是就不是。作者提到了法律,那么我就用法律的观点阐述。如果在法庭上,法官的宣判词这样写:xxxx做的太过分了,做的坏事太多了,应该判20年,而且不得保释,而且xxxx是罪有应得,这是合理的判决“,如果法官要这么判,估计是要做到头了。正常的宣判词应该是:”xxxx由于触犯了某某某法律的某某某条款,并且做伪供,拒不交代犯罪事实,经过调查取证,证据确凿(此处省略5000字的具体犯罪事实),应该按某某某条款顶格判决,判处有期徒刑20年“,后一种说法每一条都是明确到底应该按着什么标准去量刑,不是用各种形容词,那是人治,不是法治。

因此我认为,《Python到底是强类型语言,还是弱类型语言?》这篇文章以及其他类似文章犯的一个最大的错误就是用了很多不确定的词来描述强类型和弱类型,这一点是对科学观点阐述的大忌。 不确定的词只能用在文学和艺术上。

不管《Python到底是强类型语言,还是弱类型语言?》这篇文章的观点是否正确,用了太多形容词以及不确定词语,本身就是问题,为何静态语言和动态语言不会产生争议,而强类型和弱类型会产生争议,其实这本身就是个问题。只有定义不明确,存在歧义的结论才会产生争议。按着作者的说法,就应该修改或废弃这个观点。

作者的观点:

按着作者上面说的,这个隐式转换的合理性和过分性明显存在歧义,你无法界定到底什么算合理的,什么算过分的。当然,有的读者可能会说:大多数人认可的就是合理的。 但这些人不要忘了,还有一句话:真理往往是掌握着少数人手里的。 难道还要对这句话进行投票表决是否合理吗?再后再对表决结果进行投票表决是否合理?这是递归吗?而且是无限循环,小心overflow。

另外,作者也举了一些老外给出的解释,这些解释有的我看过,有的我确实没看过,不过其实都一样,大多都是支持Python是强类型语言的。不过看到有一个提法:“对类型的弱检查”,这个还贴点边。不过更合理的说法是”对类型的弱处理“,而不是弱检查。类型检查任何语言必须做,都是强检查,否则你怎么做隐式类型转换呢?不知道类型,还转换个屁啊! 只是检查的处理结果不同,有的就隐式转换了(如js),有的就抛出异常了(如python)。所以对Python的准确描述应该是:Python是一种动态的,而且类型弱处理的编程语言。

下面就对《Python到底是强类型语言,还是弱类型语言?》的一些观点进行驳斥。原文以截图形式给出。

1. 作者观点:

我的观点:

这句对强弱类型的定义还是前面描述的问题,啥叫“很少(合理)、较多(过分)”,无法界定,不同人理解不同。你认为不合理,我认为合理。就像“1000" - 1,你认为string和int不应该相减,我认为可以。这个没办法辩论,谁也无法说服谁。就像美国对华为的禁令,中国人肯定是认为不合理的,美国耍流氓,但站在不同的角度,如果你是美国人,会认为是合理的,因为这是为了美国的国家和人民利益,因为中国发展超过了美国,会对美国的经济造成非常严重的后果。所以一个人的经验、背景、经历不同,对这些不确定的事物理解会不同。没有绝对的好人,也没有绝对的坏人,就和金庸武侠小说一样,坏人也有柔情的一面,好人也有可恨的一面。很少,非常多、过分也是一样,既然没有绝对的,那么就无法进行准确判断,就存在歧义,就需要改变或废止(这是原作者的意思)。

2. 作者观点:

我的观点:

没错,变量的确是标签。我将变量比喻成超市储物箱的号码。 你是01号,就应该到01号箱子去取东西,是不能打开02号箱子的。其实不光是Python,所有的编程语言,只要有变量的概念,变量都是标签。其实从底层来看。任何一个作用域都会有一个符号表,相当于一个map。所有的变量都将作为map中的key,而变量的具体的值(就是对应内存块中的东西)就作为map中的value(实际实现可能会比这个更复杂,可能会用到B+树或更复杂的数据结构,这里就是举个例子)。Java语言的处理过程是,一旦确定x的类型是int,这个key就是x,value就int类型的值。再保存string类型,不让你保存了。而Python的处理方式是,一开始x是int类型,如果再保存一个string类型的值,那么会先将原来的int的值从这个map中弄出来(或做记录,可能是其他方式),然后准备释放内存。再将x和string类型的值重新放到map中。这就是区别。

另外,啥叫x本身的类型。 x是箱子的编号,都是将其与具体的内存块绑定才会有类型的,python是这样,java也是这样。一个编号离开箱子,啥也不是。只有编号与箱子绑定,才能知道箱子里是什么(相当于数据类型和具体的值)。Java相当于如果规定了编号(如01)是某个箱子,那么这个箱子里只能放固定的物品(如皮鞋、衣服等)。而Python相当于如果01号箱子,一开始放的电脑(一种数据类型),如果我要往01号箱子里放衣服(另外一种数据类型),我干脆新打开一个箱子(以前没有编号,相当于新分配一块内存空间),然后将01编号从原来的箱子上拿下来,放到这个新打开的箱子上。然后原来的箱子就没有编号了(python内存回收器会释放这样的箱子)。这两种方式的共同点是每一个箱子都只能放固定的东西,不同点是,java不会另打开一个新箱子,而Python会这么做。这就是python的效率比java低的原因之一。

还有就是在python中可以通过id(x)得到变量的地址,如果为变量x赋值,那么x就换一个地址(同一个数据类型也是这样),这就意味着,Python只要为变量赋值,就会重新分配一个内存空间。哪怕是类型相同的值。然后将x(编号)换到新的内存空间(箱子)了。个人感觉Python需要改进一下,如果是类型相同,就不换内存空间了。不过也很难做到,因为Python可以处理无限长度的数值,所以很难利用原来的内存空间,哪怕都是int类型。没办法,谁让python这么设计呢。灵活带来了性能低下。

3. 作者观点:

我的观点:

这个其他Python编译器如果存在,不太可能支持非常广泛的隐式类型转换,因为这需要考虑代码的兼容性。但却可能支持部分被认为不合理的隐式类型转换,如string - int。你无法说这种类型是将string转换为int合理,还是将int转换为string合理,或者都合理,或者都不合理。再说,合理凭啥由某些人来定啊。你们有啥权利呢?

PS:其实string - int就算不做类型转换,也可以让其是合理的。语义可以这样认为,如"abcdefg" - 4,可以认为是去掉该字符串的后4个字符,结果就变成了"abc“。毕竟最终解释权归编译器。

4. 作者观点:

我的观点:

没错,这些关于js的语法都没问题。这只能说明js处理数据类型更灵活,你怎么能说js是过分呢? 语言就是让代码更加少,更灵活才对。其实大多数编程语言也正是向这个方向靠拢。只是为了考虑到兼容性,大多数语言跨的步子没这么大而已。这些根本不能作为判断强弱类型的标准。

还有就是,作者所说的强弱类型是用隐式类型转换进行判断的。合理的隐式类型转换就是强类型,不合理的就是弱类型。ok,那我还认为JavaScript是强类型语言呢!你看,JavaScript在处理类型方面是多么强啊。连true == ['1']都可以将['1']转换为1,处理类型这么强,难道不是强类型语言吗?像Java,类型处理太弱了,连“1000" - 1都不支持,这还不是弱类型语言。简直太low了。就和个人能力一样。达芬奇会的太多,当然可以说达芬奇的个人能力很强,业务很全面了。一种语言处理类型的功能非常强大,非常灵活,难道不能说这种语言是强类型语言吗?也就是拥有强大的类型处理系统。

当然,我认为上面的观点同样是错误的,因为你无法给出一个量化的标准,到底怎样的类型处理能力算强呢?javascript也有其处理不了的情况,例如,给出这样的情况。 'abcd1234' / 1234。我期望将1234转换为string,变成'1234’,然后去掉分子尾部的1234,结果变成'abcd',现在javascript就做不到。也可以认为不够强大。当然,你可能会说这么做不合理,没人会这么做。其实我认为,只要可以出结果的,都是合理的。既然不合理,怎么会出结果呢,应该无论如何都不可能有结果的。总之一句话:存在就是合理的,那么只是从理论上存在。

5. 作者观点

我的观点:

其实C++属于强类型、弱类型,我已经懒得说了。作者的意思就是C++的很多隐式类型转换都是不合理的,所以C++是弱类型语言。C++的类型确实非常复杂,这一点毋庸置疑。不过用非常复杂的东西去为某些东西分类,本身就有问题。

这就和对男性和女性的分类,特点本来就非常简单(大家都清楚)。你如果用一个非常复杂的公式去对男性和女性进行分类,如根据性格、肤色、习惯等去计算,估计很多人会早中晚性别都不固定了。所以我的观点是凡是用于分类的属性,都应该是简单的,不会有任何歧义的。例如,对静态和动态的分类。就是在运行时,变量的类型会不会改变,以及是否可以动态为对象或类添加成员等。这些规则非常简单,也不会有任何歧义。如果某个分类属性,还需要看若干篇论文,去花很长时间去分析,而且结论还不可量化。这本身就是不可取的。因为越复杂,产生的争论就会越多。

当然还有很多人会说,你看,xxxxx社区的很多人都支持这种说法。也许是,但你别忘了,之所以电视广告会存在,是因为绝大多数人都会效仿身边的人或名人,这是人类基因中的bug之一,可以将其称为”群体跟随“。例如,我很久以前做过一个实验。在某个超市有两个滚梯。有一个滚梯上很多人,另一个滚梯上没有人。这些人之所以都上这个人多的滚梯,主要是因为有很多人都在这个滚梯上,所以潜意识地就会跟随(绝大多数人都没有意识到自己受到潜意识的控制),我在底下观察了好几分钟,竟然没有一个人上那个没有人的滚梯,然后我第一个走上了这个没有人的滚梯,结果后面一堆人跟着我上来了,这也是一种”群体跟随“效应。当然,这里还有人类基因的另外一个bug:疑心。 之所以会找名人做广告,主要目的是因为本来很多人都怀疑这个商品是否好,结果有个非常出名的 演员用了这个商品(其实可能根本就没用),所以这些人就会打消顾虑。 某个论点也是一样,一旦某个比较有名的所谓“大咖”说了某个观点,就会有很多所谓的跟随者,并且打消了自己的疑虑,反正这个“大咖”也这么说了,估计没错,我也这么认为吧。其实这根本就不是他们自己的想法,只是这些“大咖”的想法的快照而已。

作者的其他观点我就不一一反驳了,看我下面的结论。

现在总结下吧,我的最终结论:

我不想讨论什么强类型和弱类型,因为没必要,Python现在不是强类型和弱类型的问题,是压根就不能这么分类。因为这么分类会带来非常多的不确定性,而科学是严谨的,不允许有任何不确定性。隐式类型转换只是语言的特性之一。隐式类型转换实现的方式非常多,有的是在语言层面的,有的是在编译器层面的,有的是在运行时层面的。并不能将大多数人都认为的观点作为论据。就这几百年前,大多数人还认为地球是平的呢,只有极少数人认为地球是圆的,而且绕着太阳旋转,结果被烧死了。历史一次又一次证明,真理往往是掌握在少数人的手里,历史才是最好的论据。

如果非要用数据类型分类,那么Python应该是一种动态的,类型弱处理(或强处理)的语言。可能有读者会问,到底是类型弱处理,还是类型强处理呢? 其实这要看如何定义强和弱了。如果将该转换的不转换直接抛出异常称为强,那么Python就是类型强处理。 如果将处理数据类型的灵活度称为强,那么Python就是类型弱处理语言。

其实吧,我个人认为,不管是强弱类型,还是强弱处理,都不太合适。因为这个强弱是形容词,无法量化,所以必然存在争议。除非将具体的特性给规定出来。例如,只要支持string -int,而且string自动隐式转换为int的情形,就属于弱类型,否则就是强类型。如果没有这方面的规定,就不要用强弱类型来为语言分类了,当然,说说是可以的。就像说PHP是世界上最好的编程语言一样,no problem.

编程语言类型的强弱只是一个形容词,怎能用来对编程语言进行分类相关推荐

  1. 【数据库系统】编程语言类型说明系统和DDL的区别

    编程语言类型说明系统和DDL的区别 DDL:数据定义语言 在DDL中执行动作会导致在数据库中创建对象:相反,编程语言类型声明只是程序中使用的抽象. 数据库DDL允许指定一致性约束(域约束和参照完整性约 ...

  2. 创造一个计算机语言,世界上第一个文言文编程语言诞生,创造它的是一个大学生...

    究竟是怎么用古文来编程的呢? 夫唐.虞之世,結繩而足治,屈指而足算.是時豈料百代之後,計算機械之巧,精於公輸之木鳶,善於武侯之流馬:程式語言之多,繁若<天官>之星宿,奇勝<山經> ...

  3. Java框架技术核心基石系列教程(01)——编程语言类型及其特征

    版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 开篇语 近十几年来,在Java和Android开发领域中涌现出许多优秀的框架,比如:Sprin ...

  4. html 循环_一个不被程序员认为是编程语言的语言——HTML,你怎么看?

    HTML究竟算不算是一门编程语言,这是争执已久的话题.其实,从本质来讲,HTML确实算不上是一门编程语言. HTML全称,HyperText Markup Language.字面理解,HTML就是一种 ...

  5. 使用Zabbix的SNMP trap监控类型监控设备的一个例子

    转载来源 :使用Zabbix的SNMP trap监控类型监控设备的一个例子 :https://www.jianshu.com/p/aa795afdf655 介绍 本文以监控绿盟设备为例. 1.登录被监 ...

  6. 【Zabbix-SNMP trap】使用Zabbix的SNMP trap监控类型监控设备的一个例子

    本文以监控绿盟设备为例. 1.登录被监控的设备的管理系统,配置snmptrap地址指向zabbix服务器或代理服务器. snmptrap地址也叫陷阱. 2.配置或关闭防火墙,并验证是否能在zabbix ...

  7. 元数据编程将编程语言的语义提高了一个层次

    元数据编程,在jdk1.5叫Annotation,在ms叫属性化编程.只需要在普通类前面加上Annotation或Attribute,就可以得到想要的特性,比如O/R mapping,比如将一个类变成 ...

  8. 作为一个形容词的2050

    在2050大会的这几天,我一直处在亢奋之中,值得记录的事情,实在是太多了.在和许许多多的朋友交谈过程中,我发现大家往往都会聊到同一个话题:2050是什么?甚至在形容一个事物的时候,往往会说:" ...

  9. python编程语言-为什么Java、Python会成为程序员最害怕的编程语言?

    声明:本文来自于微信公众号 InfoQ(ID:infoqchina),作者:Mike Loukides,授权站长之家转载发布. 这是 O'Reilly 发布的"The Least Liked ...

最新文章

  1. 谜题59:什么是差?
  2. RookeyFrame 删除 线下添加的model
  3. struts深入理解之登录示例的源码跟踪
  4. weblogic 安装教程
  5. 分页原理+分页代码+分页类制作
  6. Cloud for Customer里employee视图打开时的渲染逻辑
  7. linux下的awk程序在哪里编写,如何编写awk命令和脚本
  8. [振动力学]期中复习
  9. xp系统打开计算机配置文件,浅析xp系统如何解决开机出现“Windows不能加载本地存储的配置文件“...
  10. Atitit uke协会产业分类法 艾提拉产业分类法五大类法 目录 1. 配第-克拉克定理概述 产业趋势 有形财物的生产转向无形的服务性生产 1 1.1. 农工商趋势法 1 1.2. 1940年,英
  11. SLAM--BA优化
  12. web应用系统性能测试的种类
  13. linux打开cap文件,cap/pcap类文件无法用wireshark打开
  14. 最小二乘法简解及空间直线拟合
  15. 关于opencv fitLine直线拟合得斜率及截距
  16. 达人评测 RTX3060和RX 6600M选哪个好
  17. 基于音频指纹技术的微信“摇一摇搜歌”和QQ音乐“听歌识曲”
  18. 蓝桥杯每日一练:报时助手
  19. 玩homegrownpet遇见unable to find vl gothic fonts
  20. ORA-00257 archiver error 解决方案

热门文章

  1. 从图像中删除不想要的东西。
  2. 黄山市对口升学计算机技校,黄山市及各县个高中、中专、技校有那些?
  3. Spring中将对象交给容器去管理的注解
  4. 【Js】删除字符串后3位
  5. 信通院“5G+工业互联网”产业政策分析
  6. 2021遥感应用组二等奖:基于机器学习回归算法的鄱阳湖水质遥感定量反演及时序变化监测研究
  7. Wireshark 用户使用手册 ———— Telephony 模块
  8. 探究CPU等设备频率、电压、功耗的关系 —— Linux中的OPP_table与energy model
  9. 意味着你面试有戏的6大信号|智测优聘总结
  10. [附源码]JAVA+ssm计算机毕业设计高考志愿智能填报系统(程序+Lw)