在Python中引入不可变对象的目的是什么?
是否与使用参考模型的Python有关(即变量是指向对象而不是容器的指针 对象'价值观)?
我猜不是,因为Python使用所有类型的参考模型, 并非所有类型都需要不可变对象。
Python中的不变性是否被用作功能范式的一部分?如果是,怎么样?
例如,我们不能通过分配一个字符串来更改字符串 位置。
>>> S
'Spam'
>>> S[0] = 'z' # Immutable objects cannot be changed
...error text omitted...
TypeError: 'str' object does not support item assignment
但我们总是可以建立一个新的并将其指定为相同的名称。 这是否背叛了功能性不变性的目的 范式,并与命令式范式一致?但在命令式范式中,在不变性和参考模型方面实现可变性是低效的。
>>> S = 'z' + S[1:] # But we can run expressions to make new objects
>>> S
'zpam'
某些类型被设计为使用不可变对象(数字,字符串,元组)的原因是什么,而其他类型(列表,字典,集合)使用可变对象,而不是所有类型都是不可变的或可变的?
是否有一些规则用于判断某种类型是否需要不变性或可变性? 原始对象(即与复合对象相对)是否必须是不可变的?
感谢。
答案 0 :(得分:1)
在Python中引入不可变对象的目的是什么?
在任何语言中引入不可变对象有什么意义?
...我们不能通过指定其中一个位置来更改字符串...但我们总是可以构建一个新字符串并将其指定为相同的名称。这是否背叛了功能范式中不变性的目的,并与命令式范式保持一致?但在命令式范式中,在不变性和参考模型方面实现可变性是低效的。
实现并非少见,实际上 - C#字符串以完全相同的方式实现(对不可变对象的可变引用)。
某些使用字符串数组的语言(如C)具有事实不可变字符串长度(但每个字符都是可变的)。
请记住,“不变性”有许多相互竞争的定义。 (我读了一篇论文,列出并解释了所有这些,但我现在无法找到它)。例如,它是否意味着对可变对象的持续引用(浅不变性)?或者对不可变对象的持续引用(深度不变性)?甚至是对不可变对象的“非固定”引用?这实际上取决于您希望如何“深入”实现不变性以及如何在不“破坏”向后兼容性的情况下实现它。 (关于向后兼容性问题,请注意C ++,C#,Java,F#和许多其他语言实际上必须为常量变量引入特殊关键字 - 例如Java中的final
,F#中的let
,{{ 1}}在C#中。
另一点:许多语言(C#,Python)具有功能性功能,而不一定是纯粹(甚至主要)功能性语言本身。很多时候(例如在C#中),功能特性在技术上是语言的新增功能,因此为了保持向后兼容性,某些功能特性可能不会像您所希望的那样以“纯粹”的功能样式实现。
此外,允许多种范式的部分后果是,您通常可以以并非总是完全健康的方式“混合”它们 - 通常很难或不可能从法律角度“禁止”范式混合图。
某些类型被设计为使用不可变对象(数字,字符串,元组)的原因是什么,而其他类型(列表,字典,集合)使用可变对象,而不是所有类型都是不可变的或可变的?
因为Python是一种多范式语言。不可变数据类型适用于函数式编程,但通常需要可变数据类型进行面向对象编程。因此,语言必须具有适合两种范例的特征。正如official documentation on Python's functional features所述,
某些计算机语言的设计者选择强调一种特定的编程方法。这通常使编写使用不同方法的程序变得困难。其他语言是支持多种不同方法的多范式语言。 Lisp,C ++和Python是多范式的;您可以编写在所有这些语言中主要是程序,面向对象或功能的程序或库。在大型程序中,可以使用不同的方法编写不同的部分;例如,GUI可能是面向对象的,而处理逻辑是程序性的或功能性的。
所以,基本上,Python希望允许你选择你的范例(甚至可以在同一个程序中混合它们)。这实际上非常方便 - 许多框架(例如.NET)现在都在鼓励它。 (例如,WPF / XAML倾向于鼓励GUI的声明范例。)