2011-08-03 12 views
8

¿Por qué el intern de Python está incorporado solo para cadenas? Debería ser posible ampliar intern a clases que son aptas para ser manejables y comparables, ¿verdad?Interno de Python para cadenas

+1

Puede crear un caché de objeto como 'interno 'para objetos inmutables. –

+0

@Peter: tienes razón. La ventaja de 'intern' es que todo el código para eso se genera automáticamente, y como una bonificación, está en C++ rápido. –

+2

@NeilG No lo creo. AFAIK CPython está completamente escrito en C, no en C++. – glglgl

Respuesta

14

El propósito de las cosas internas es poder compararlas comparando su dirección de memoria; se asegura de que nunca cree dos objetos con el mismo valor (cuando el programa solicita la creación de un segundo objeto con el mismo valor que un objeto existente, en su lugar recibe una referencia al objeto preexistente). Esto requiere que las cosas que está intercediendo sean inmutables; si el valor de un objeto interno puede cambiar, compararlos por dirección no va a funcionar.

En Python, no es posible imponer la inmutabilidad de instancias de clases definidas por el usuario, por lo que no sería seguro internarlas. Sospecho que esa es la principal razón teórica por la que el interno no cubre las instancias de clase.

Otros construido en tipos inmutables son ya sea comparable en una sola operación a nivel de máquina ya (int, float, etc), o recipientes inmutables que puede contener valores mutables (tupla, frozenset). No es necesario internar al primero, y este tampoco puede ser internado de manera segura.

+0

+1. "En Python, no es posible imponer la inmutabilidad de instancias de clase definidas por el usuario": qué desafortunado. – ShreevatsaR

0

Solo se admiten cadenas porque la internación se basa en un object identity test basado en puntero. Se pueden comparar hash de otros tipos de clases, pero los objetos nunca coincidirán con una prueba de identidad. Esto es cierto porque, aunque pueden ser idénticos, no son los mismos objetos.

Reference

+3

Según tengo entendido, la prueba de identidad de objeto basada en puntero es el * beneficio * que obtienes por pasantía, no lo que se requiere para internar cosas. Si está pidiendo objetos internos, está considerando intrínsecamente a dos de ellos con el mismo valor para tener la misma identidad (que creo que es a lo que llega Neil G cuando dice "accesible y comparable"). Eso a su vez requiere que sean inmutables, lo cual no es una propiedad exigible de instancias de clase en Python. Supongo que esa es la principal razón teórica por la que no es compatible. – Ben

+0

@Ben: Esa es una buena interpretación de mi pregunta. Además, su último punto es probablemente la respuesta a esta pregunta. Siéntase libre de agregar una respuesta. –

1

No hay ninguna razón técnica que, por ejemplo, una tupla no podía ser internado, aunque me imagino que en el mundo real, esto es de poco valor en comparación con los literales de cadena, y sería incluso menos valor en el mundo real con tipos definidos por el usuario. Hacer que funcione probablemente no se considera que valga la pena el esfuerzo.

+5

El contenido de una tupla puede ser mutable. Las tuplas de internamiento pueden causar un comportamiento extraño. P.ej. 'a, b = ([]), ([]); a [0] .append ('foo') 'tendría diferentes resultados dependiendo de si' a' y 'b' eran tuplas diferentes que dependen de la implementación de la interpelación de tupla. Al parecer, algunas implementaciones de Fortran [hicieron algo similar] (http://stackoverflow.com/questions/1995113/strangest-language-feature/1995476#1995476). –

+2

@Peter: la idea general de la práctica es que puedes hacerlo solo cuando no hay efectos secundarios como el que describes. La internación de una tupla obviamente tendría que verificar para asegurarse de que todos los elementos sean los mismos objetos que una tupla ya internada, no meramente igual. De hecho, podría tratar de internar los elementos primero (esto sería más útil si los tipos numéricos también se hicieran internables). En su ejemplo, las tuplas simplemente no podrían compartir una referencia si no contenían la misma lista. No hay ninguna razón técnica por la que Python no pueda ser modificado para hacer todo esto. – kindall