2011-06-06 10 views
8

En Python 2.7, que definen un vacío de clases de nuevo estilo:Python: comparación predeterminado

In [43]: class C(object): pass 
    ....: 

continuación, crear una lista de casos de la nueva clase:

In [44]: c = [C() for i in xrange(10)] 

después intenta ordenar la lista:

In [45]: sorted(c) 
Out[45]: 
[<__main__.C object at 0x1950a490>, 
<__main__.C object at 0x1950a4d0>, 
... 
<__main__.C object at 0x1950aad0>] 

lo que es sorprendente es que el tipo no se queja, a pesar de que no he definido una forma de comparar Instan ces de C:

In [46]: dir(C()) 
Out[46]: 
['__class__', 
'__delattr__', 
'__dict__', 
'__doc__', 
'__format__', 
'__getattribute__', 
'__hash__', 
'__init__', 
'__module__', 
'__new__', 
'__reduce__', 
'__reduce_ex__', 
'__repr__', 
'__setattr__', 
'__sizeof__', 
'__str__', 
'__subclasshook__', 
'__weakref__'] 

¿Qué es exactamente que está ocurriendo allí, y ¿cuál es la razón para esto - podría decirse que es sorprendente - la conducta?

Respuesta

14

Creo que la única razón es que es conveniente que los objetos se puedan ordenar y, p. utilizado como claves de diccionario con algún comportamiento predeterminado. El capítulo correspondiente en la definición de idioma está aquí: https://docs.python.org/2/reference/expressions.html#not-in

"La elección de si un objeto se considera más pequeño o más grande se realiza de forma arbitraria pero consistente dentro de una ejecución de un programa."

Por lo tanto, el hecho de que los objetos se comparen actualmente con la dirección de memoria es solo un detalle de implementación con el que no se puede contar. La única garantía es que el pedido se mantiene constante durante la ejecución.

+0

(+1) para el enlace y la cita. – NPE

+0

+1, tenías toda la razón en tu comentario, me indujo a error la igualdad entre dos objetos y otro operador de comparación, gracias por descubrir mi error – mouad

+0

Enlace actualizado http://docs.python.org/reference/expressions.html #no en –

0

Mire los valores cuando lo imprima. Observe el número hexadecimal al lado del "Objeto C en"? Esa es una referencia de puntero. Se puede equiparar grosso modo con el orden de creación. Si repites esa lista, verás que ha ordenado los objetos usando eso como estándar.

Como nota al margen, recuerdo haber sido confused por las comparaciones Python 2.x ... pero no sé si esto, en particular, se corrigió en Py3k.

+0

Sí, he notado eso. Pero, ¿cuál es el razonamiento? – NPE

+1

@aix Ver la edición. Python <3 hizo la comparación casi molestamente fácil. Ver http://stackoverflow.com/questions/4266918/why-is-int50str5-in-python-2-x – cwallenpoole

+0

La razón fundamental es que las variables en python son referencias a objetos en el montón. Ordenar por la dirección de la memoria era probablemente el comportamiento predeterminado más fácil de implementar que los desarrolladores de Python podían pensar. –

1

No estoy exactamente seguro, pero tal vez alguien me puede corregir esto.

Al comparar objetos, compara su dirección de memoria, piense en comparar 2 cstrings en C. Si echa un vistazo, la ordenación clasificó los objetos desde la dirección de memoria más baja hasta la dirección de memoria más alta (o ubicación del puntero).

+0

De hecho, ¿pero esto no parece un poco arbitrario y, por lo tanto, bastante antiponético? – NPE

+0

Bueno, en el código C subyacente, cuando se compara 2 objetos, simplemente se compara 2 enteros, que apunta a la memoria en la que se almacena el objeto, y todos sabemos cómo funciona la comparación de enteros. – Pwnna

Cuestiones relacionadas