Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
非字符串的Python实习生_Python_Language Features - Fatal编程技术网

非字符串的Python实习生

非字符串的Python实习生,python,language-features,Python,Language Features,为什么Python的intern只内置于字符串中?应该可以将intern扩展到可散列和可比较的类,对吗?只支持字符串,因为interning依赖于基于指针的类。可以比较其他类型的类的散列,但是对象本身永远不会匹配身份测试。这是真的,因为即使它们可能是相同的,但它们不是相同的对象 没有技术上的原因,比如说,元组不能被插入,尽管我可以想象,在现实世界中,这与字符串文字相比没有什么价值,对于用户定义的类型,它的实际价值甚至更低。让它工作起来可能不值得努力。实习的目的是通过比较它们的内存地址来比较它们;

为什么Python的
intern
只内置于字符串中?应该可以将
intern
扩展到可散列和可比较的类,对吗?

只支持字符串,因为interning依赖于基于指针的类。可以比较其他类型的类的散列,但是对象本身永远不会匹配身份测试。这是真的,因为即使它们可能是相同的,但它们不是相同的对象


没有技术上的原因,比如说,元组不能被插入,尽管我可以想象,在现实世界中,这与字符串文字相比没有什么价值,对于用户定义的类型,它的实际价值甚至更低。让它工作起来可能不值得努力。

实习的目的是通过比较它们的内存地址来比较它们;确保从不创建具有相同值的两个对象(当程序请求创建与现有对象具有相同值的第二个对象时,它会收到对该现有对象的引用)。这要求你实习的东西是不变的;如果一个内部对象的值可能会改变,那么按地址比较它们是行不通的

在Python中,不可能强制执行用户定义的类实例的不变性,因此对它们进行内部实习是不安全的。我怀疑这是intern不涵盖类实例的主要理论原因


其他内置的不可变类型要么已经在单个机器级别的操作中具有可比性(int、float等),要么可以包含可变值的不可变容器(tuple、frozenset)。前者不需要实习,后者也不能安全实习。

你可以像
intern
那样为不可变对象创建对象缓存。@Peter:你说得对。<代码>实习生的优点是所有的代码都自动生成,作为奖励,它是在快速C++中。Afik cPython完全是用C编写的,而不是C++。元组的内容可以是可变的。插入元组可能会导致奇怪的行为。例如,
a,b=([]),([]);a[0]。append('foo')
将产生不同的结果,这取决于
a
b
是否是不同的元组,这取决于元组的内部实现。显然是Fortran的一些实现。@Peter:实习的全部想法是,只有在没有你所描述的副作用的情况下,你才能实习。插入一个元组显然需要检查以确保所有元素都是与已经插入的元组相同的对象,而不仅仅是相等的。实际上,它可以首先尝试将元素内部化(如果数字类型也可以内部化,这将更有用)。在您的示例中,如果元组不包含相同的列表,它们将无法共享引用。没有技术上的理由不能修改Python来完成这一切。据我所知,基于指针的对象标识测试是通过实习获得的好处,而不是实习所需的东西。如果你要求实习生对象,你本质上是在考虑具有相同值的任意两个对象具有相同的身份(我相信这就是Neil G所说的“hashable and comparable”)。这反过来又要求它们是不可变的,这在Python中不是类实例的可执行属性。我想这是它不被支持的主要理论原因。@Ben:这是对我问题的一个很好的解释。另外,你的最后一点可能就是这个问题的答案。请随意添加答案。+1。“在Python中,不可能强制用户定义类实例的不变性”——多么不幸。