为什么在Python中不可能实现真正的不变性?

米拉德·阿加霍里

我正在阅读attrs的文档它说:

请注意,在Python中不可能实现真正的不变性

我想知道是什么原因。为什么在C ++中可能有人在Python中没有不可变列表?这里的主要区别是什么?

亚伦

TLDR; “真正的不可变性”只能在不透水的石板上使用,但对可变性及其用途的重要性起反作用。技术上的正确性以牺牲实际的错误为代价是不值得的

这是语义上的错误论点。Python允许使用其他类型的强类型语言重新定义具有不同类型的变量名,这是造成某些混淆的地方,但是要清楚,变量名所指的对象可能是非常不可变的。

以其中包含一些数字的元组为例:

>>> tup_A = (1,2,3)

不能更改元组中任何对象的值:

>>> tup_A[0] = 10
TypeError: 'tuple' object does not support item assignment

可以tup_A用其他一些值覆盖变量名,但是即使它与原始名称相关,它也将是一个完全不同的对象。例如,一个元组的切片会创建一个全新的对象,而不是原始对象的视图:

>>> id(tup_A)
2887473131072
>>> tup_A = tup_A[:1]
>>> id(tup_A)
2887473037616

我相信所提到的文章可能在某种程度上还涉及创建自定义不可变类型(类)的可能性。这也是一个不好的论据,因为有很多强制不变性的机制。特别是,用于定制属性访问的工具以及该@property功能可以极大地发挥作用。一旦使用了这些方法来实现不变性,就必须故意破坏该类以使不希望被突变的数据发生突变。这当然是可能的,因为python主要是作为源代码分发的,但是从理论上讲,对于python c api也可以这样说。如果您重新编写python,元组不必是不变的,但这远远超出了要点,可以公平地说这是错误的。

不变性是具有特定目的的工具。尽可能使用它是一个好主意,这样意外的滑动会产生错误消息,而不是无声的错误。如果遇到这样的错误,则永远不要问“我该如何改变原定为不可变的值?”,而是问“为什么不打算改变该值?我打算如何利用它? ”

PS您甚至可以通过获取包含在其中的对象的实际内存位置并覆盖指针,而无需使用ctypes库来编辑cpython,甚至可以对元组进行变异,但这会破坏很多事情(例如垃圾收集引用计数)。不要这样 这是那些“远远超出重点”的事情。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Java

Java中强不变性与弱不变性?

来自分类Javascript

为什么不变性在JavaScript中如此重要(或需要)?

来自分类Java

在Java中,是否在实现String.format()时考虑了字符串的不变性?

来自分类Java

Java的不变性

来自分类Dev

为什么在C中不可能重载?

来自分类Dev

为什么在Haskell中不可能分割整数?

来自分类Dev

为什么这个Rust程序会忽略不变性

来自分类Dev

如何在Java 8流API中实现不变性

来自分类Dev

什么是深度不变性?

来自分类Dev

状态信息和Python中列表的不变性

来自分类Dev

如何实现不变性

来自分类Dev

Python字符串-字符串的不变性

来自分类Dev

通过类型别名实现C ++不变性

来自分类Dev

Hyperledger Fabric的不变性

来自分类Dev

如何避免Redux中的不变性

来自分类Dev

为什么可以在TypeScript中将接口中可能的数字值转换为类实现中的不可能的数字值?

来自分类Dev

没有执行循环裂变/不变性优化,为什么?

来自分类Dev

人偶变量不变性

来自分类Dev

简单并发程序的归纳不变性是什么?

来自分类Dev

ReactJS和不变性

来自分类Dev

Scala设置不变性

来自分类Dev

Scala中Java对象的不变性

来自分类Dev

Java:整数不变性

来自分类Dev

Scala Streams 如何实现不变性?

来自分类Dev

Clojure 不变性实践

来自分类Dev

deepFreeze 和真正的不变性之间有什么区别

来自分类Dev

Postgres 中的不变性

来自分类Dev

什么是排名上下文中的右不变性?

来自分类Dev

当 JavaScript 没有提供任何明显的实现不变性的方法时,人们如何在 JavaScript 中实现不可变的数据结构?