Sé que Python tiene una len()
función que se utiliza para determinar el tamaño de una cadena, pero me preguntaba por qué no es un método del objeto de cadena.
Actualizar
Ok, me di cuenta de que estaba vergonzosamente equivocado. __len__()
es en realidad un método de un objeto de cadena. Simplemente parece extraño ver código orientado a objetos en Python usando la función len en objetos de cadena. Además, también es raro verlo __len__
como el nombre en lugar de solo len.
len
. Piensan que es más fácil obligar a las personas a implementar.__len__
que obligar a las personas a implementar.len()
. Es lo mismo, y uno se ve mucho más limpio. Si el idioma va a tener un OOP__len__
, ¿cuál es el objetivo del mundolen(..)
__iter__
, o con solo__getitem__
, yiter(x)
funcionará de cualquier manera. Puede crear un objeto de contexto utilizable en bool con__bool__
o__len__
, ybool(x)
funcionará de cualquier manera. Y así. Creo que Armin explica esto razonablemente bien en la publicación vinculada, pero incluso si no lo hizo, llamar a Python imbécil debido a una explicación externa de un tipo que a menudo está públicamente en desacuerdo con los desarrolladores principales no sería exactamente justo ...zip
es una función de nivel superior, no unzip_with
método. Y así. El hecho de que todo sea un objeto no significa que ser un objeto sea lo más importante de cada cosa.La respuesta de Jim a esta pregunta puede ayudar; Lo copio aquí. Citando a Guido van Rossum:
fuente
Hay un
len
método:fuente
Python es un lenguaje de programación pragmática, y las razones de
len()
ser una función y no un método destr
,list
,dict
etc, son pragmáticos.La
len()
función incorporada trata directamente con los tipos incorporados: la implementación de CPythonlen()
realmente devuelve el valor delob_size
campo en laPyVarObject
estructura C que representa cualquier objeto incorporado de tamaño variable en la memoria. Esto es mucho más rápido que llamar a un método: no es necesario realizar ninguna búsqueda de atributos. Obtener el número de elementos de una colección es una operación común y debe trabajar de manera eficiente para los tipos básicos y diversos tales comostr
,list
,array.array
etc.Sin embargo, para promover la coherencia, cuando se aplica
len(o)
a un tipo definido por el usuario, Python llamao.__len__()
como reserva.__len__
,__abs__
y todos los demás métodos especiales documentados en el Modelo de datos de Python facilitan la creación de objetos que se comportan como los integrados, permitiendo las API expresivas y altamente consistentes que llamamos "Pythonic".Al implementar métodos especiales, sus objetos pueden soportar la iteración, sobrecargar operadores infix, administrar contextos en
with
bloques, etc. Puede pensar en el modelo de datos como una forma de usar el lenguaje Python como un marco donde los objetos que crea se pueden integrar sin problemas.Una segunda razón, respaldada por citas de Guido van Rossum como esta , es que es más fácil de leer y escribir
len(s)
ques.len()
.La notación
len(s)
es consistente con operadores unarios con notación de prefijo, comoabs(n)
.len()
se usa con mucha más frecuenciaabs()
y merece ser tan fácil de escribir.También puede haber una razón histórica: en el lenguaje ABC que precedió a Python (y fue muy influyente en su diseño), había un operador unario escrito como se
#s
quería decirlen(s)
.fuente
fuente
Aquí hay algunas respuestas excelentes, por lo que antes de dar la mía me gustaría destacar algunas de las gemas (sin intención de juego de palabras con rubí) que he leído aquí.
len
lo que en realidad es un objeto. Ruby, por otro lado, no tiene funciones de primera clase. Por lo tanto, ellen
objeto de función tiene sus propios métodos que puede inspeccionar ejecutandodir(len)
.Si no le gusta cómo funciona esto en su propio código, es trivial volver a implementar los contenedores utilizando su método preferido (vea el ejemplo a continuación).
fuente
También puede decir
Usando Python 2.7.3.
fuente
len
La función ya se mencionó en respuestas anteriores. ¿Cuál es el punto de esta "respuesta", entonces?Algo falta en el resto de las respuestas aquí: la
len
función verifica que el__len__
método devuelva un valor no negativoint
. El hecho de quelen
sea una función significa que las clases no pueden anular este comportamiento para evitar la verificación. Como tal,len(obj)
da un nivel de seguridad queobj.len()
no puede.Ejemplo:
Por supuesto, es posible "anular" la
len
función reasignándola como una variable global, pero el código que hace esto es mucho más obviamente sospechoso que el código que anula un método en una clase.fuente
No lo hace?
fuente