Python是一门活泼的语言 -- 不断发展以跟上时代的发展。Python 软件基金会不仅在标准库和参考实现CPython中进行了添加,而且还为语言本身引入了新功能和改进。
例如, Python 3.8为内联分配引入了新语法(“walrus运算符”),使某些操作更加简洁。另一项新批准的语法改进(模式匹配)将使编写针对多种可能情况之一进行评估的代码变得更加容易。这两种功能均受其在其他语言中的存在和实用性的启发。
而且,它们只是可以添加到Python中的一系列有用功能中的两个,以使该语言更具表现力,更强大,更适合现代编程世界。我们还希望什么?这是另外四种可以为Python增添真正价值的语言功能 -- 我们可能会真正获得其中两个,而另外两个我们可能不会获得。
### 真正的常数
Python确实没有常量的概念。如今,Python中的常量主要是约定俗成的问题。使用全大写字母和大写字母形式的名称(例如,DO_NOT_RESTART )暗示该变量旨在为常数。类似地, typing.Final 类型批注为linters提供了一个提示,即不应修改对象,但不会在运行时强制执行该操作。
为什么?因为可变性已在Python的行为中根深蒂固。例如,当您为变量分配值时, x=3 您正在本地名称空间中创建一个名称 x,并将其指向系统中具有整数值的对象 3。Python始终假设名称是可变的- 任何名称都可以指向任何对象。这意味着每次使用名称时,Python都会麻烦查找它指向的对象。这种动态性是Python运行速度比某些其他语言慢的主要原因之一。Python的动态性提供了极大的灵活性和便利性,但是却以运行时性能为代价。
在Python中拥有真正的常量声明的一个优势是可以减少运行时期间对象查找的频率,从而提高性能。如果运行时提前知道给定值永远不会改变,则不必查找其绑定。这也可以为进一步的第三方优化提供一条途径,例如从Python应用程序(Cython,Nuitka)生成机器本机代码的系统。
但是,真正的常数将是一个重大更改,并且很可能是向后不兼容的更改。如果常量将通过新语法(例如,尚未使用的$ 符号)或作为Python现有声明名称方法的扩展而来,这也将引起争论 。最后,还有一个更大的哲学问题,即在以动态性为主要吸引力的语言中,真正的常数是否有意义。
简而言之,我们可能会在Python中看到真正的常量,但这将是一个重大的突破性变化。
### 真正的重载和泛型
在许多语言中,可以编写同一功能的多个版本以使用不同类型的输入。例如,一个 to_string() 函数可能用于从整数,浮点数或其他对象进行转换的不同实现,但为方便起见,它们将共享相同的名称。“重载”或“泛型”使编写健壮的软件变得更加容易,因为您可以为通用过程编写泛型方法,而不是专门为给定类型使用方法。
Python确实允许您使用一个函数名称来完成许多工作,但不能通过定义一个函数的多个实例来完成。您只能在给定范围内定义一次名称,并且一次只能将其绑定到单个对象,因此,同一名称下不能有单个功能的多个版本。
为了解决此问题,Python开发人员通常要做的工作是使用内置 函数,例如 isinstance() 或 type()确定提交给函数的变量的类型,然后根据该类型采取措施。有时这涉及在幕后调度到特定类型的函数。但是,这种方法使其他开发人员很难扩展您的功能,除非您竭尽全力使其功能可扩展 -- 例如,通过分派到类的方法中,该方法可以被子类化。
PEP 3124(于2007年4月进行了改进)提出了一种函数的机制,以指示函数可能重载。该提议被推迟而不是被彻底拒绝,这意味着该想法从根本上是合理的,但是实施该提议的时机不正确。可能会加快在Python中采用重载或导致完全放弃该想法的一个因素是新提出的模式匹配系统的实现。
从理论上讲,模式匹配可以在引擎盖下用于处理重载。但是,模式匹配也可以作为不在 Python中实现泛型的理由,因为它已经提供了一种优雅的方式来基于类型签名分派操作。
因此,有一天我们可能会在Python中获得真正的重载,否则它的优势可能会被其他机制所取代。
### 尾部递归优化
许多语言编译器采用尾部递归优化,调用函数自身不会在应用程序中创建新的堆栈,因此如果它们运行太多次,则可能会导致堆栈崩溃。Python不会这样做,实际上它的创建者一直反对这样做。
原因之一是,很多Python从内到外都使用 迭代 而不是 递归 -- 生成器,协程等等。在这种情况下,这意味着使用具有循环和堆栈结构的函数而不是递归机制。可以将每次循环调用保存到堆栈中以创建新的递归,并在递归完成时从堆栈中弹出。
鼓励Python开发人员使用这些模式代替递归,因此似乎没有机会递归优化。由于Python的习惯用法支持其他解决方案,因此它根本不可能出现。
### 多行lambdas
Lambdas,即匿名函数,在受到语言创建者Guido van Rossum的一些阻力之后才引入Python的。Python lambda受到了极大的限制:它们仅允许使用单个表达式(本质上是赋值操作中等号右边的任何内容)作为函数体。如果你想要一个完整的语句块,需要将它们分开并从中生成一个实际的函数。
原因可以归结为语言的设计,正如van Rossum所看到的那样。vanrossum在2006年写道,“我发现任何在表达式中间嵌入基于缩进的块的解决方案都是不可接受的。由于我发现语句分组的替代语法(例如大括号或begin/end关键字)同样不可接受,这几乎使多行lambda成为一个无法解决的难题。”
换句话说,问题不是技术性的,而是缺乏多行lambda的语法来补充现有Python语法的美感。可能没有办法做到不涉及创建特例的情况,而产生特例往往会变得不好用。在出现更好方法之前,我们只能处理单独定义的函数。
多行lambda可能不会在Python中发生。