2011-05-05 12 views
6

He estado leyendo en el special class methods de python en Dive into Python, y parece que algunos métodos tienen una sintaxis impar o incoherente.Incoherencia de sintaxis de Python?

para obtener los elementos de un diccionario que llamarían los artículos método de la clase Dictionary()

>>> my_dictionary.items() 
[('name', 'Old Gregg'), ('Race', 'Scaly Man-Fish')] 

Sin embargo, para determinar el número de claves en ese diccionario que llamarían len() y le facilitará el diccionario como un argumento.

>>> len(my_dictionary) 
2 

siempre supuse que métodos como len() no eran en realidad parte de cualquier clase que ellos llaman el dado su sintaxis, pero después de leer el capítulo 5 de Inmersión en Python veo que len() realidad da lugar a un método bienestar diccionario llamado.

my_dictionary.__len__() 

¿Por qué no lo es y métodos como este se llaman como un método de clase típico?

my_dictionary.len() 

¿Hay alguna convención que desconozca?

Respuesta

12

Guido van Rossum explained it thusly:

(a) Para algunas operaciones, la notación de prefijo simplemente lee mejor que postfix - prefijo operaciones tienen una larga tradición en las matemáticas que le gusta notaciones, donde los elementos visuales ayudan al matemático (y infija!) pensando en un problema Compare la facilidad con la que reescribimos una fórmula como x * (a + b) en x a + x b por la torpeza de hacer lo mismo utilizando una notación OO cruda.

(b) Cuando leo el código que dice len(x) sé que está pidiendo la longitud de algo. Esto me dice dos cosas: el resultado es un número entero, y el argumento es algún tipo de contenedor. Por el contrario, cuando leo x.len(), tengo que saber que x es un tipo de contenedor que implementa una interfaz o hereda de una clase que tiene un estándar len(). Sea testigo de la confusión que ocasionalmente tenemos cuando una clase que no implementa una asignación tiene un método get() o keys(), o algo que no es un archivo tiene un método write().

+1

La respuesta más rápida que he recibido. Gracias, buen señor –

+0

La última parte de la explicación de/F en ese enlace también es perspicaz. Muchas construcciones tienen implementaciones predeterminadas en términos de * otras interfaces * que las clases pueden proporcionar. Entonces 'iter (x)', por ejemplo, primero intenta 'x .__ iter __()', pero también define un repliegue en términos de 'x .__ len __()' y 'x .__ getitem __ (i)'. – ncoghlan

0

No estamos en el mundo de Java.

Hay una gran cantidad de métodos en Python que son aplicables a objetar si implementan la API relacionada

len() --> __len__() 
str() --> __str__() 
repr() --> __repr__() 

Aparte de eso:

¿Por qué

my_dictionary.len() 

ser un método ?

En JavaScript los objetos exponen su tamaño mediante el atributo 'longitud' que es más natural que utilizando un método ... lo siento, pero no todas las tonterías procedentes del mundo Java son buenas y deben estar disponibles en otros idiomas.

+0

Creo que 'abs()' también entra en esa categoría. – Blender

+0

Claro, hay más métodos ... no citando la referencia de idioma completa :) –

1

Esta distinción es útil porque separa el uso de la fuente.Al codificar una extensión de la clase del diccionario, sabe que está anulando algo que está integrado en el objeto base como parte del lenguaje. Si realmente desea cambiar la forma en que se comporta un contenedor, sobrescriba __len__(), __getitem__(), etc.

Sin embargo, como usuario del código de alguien, no tengo que preocuparme por eso. Si uso len(my_dictionary), espero un comportamiento consistente basado en que un programador conozca la forma correcta de implementar __len__(). Mientras que cualquiera puede escribir un método aleatorio my_dictionary.len(). No sé de eso

Referencia http://www.siafoo.net/article/57 for WAY más información de referencia sobre los métodos de guión bajo principalmente la tangencial a su pregunta real (Sección 2.7.1 para __len__()).

+0

Estos son buenos puntos. –

Cuestiones relacionadas