¿Por qué algunos métodos usan la notación de puntos y otros no?

Entonces, estoy empezando a aprender Python (usando Codecademy), y estoy un poco confundido.

¿Por qué hay algunos métodos que toman un argumento y otros usan la notación de puntos?

len () toma una regla, pero no funciona con la notación de puntos:

>>> len("Help") 4 >>>"help".len() Traceback (most recent call last): File "", line 1, in  AttributeError: 'str' object has no attribute 'len' 

Y de la misma manera:

 >>>"help".upper() 'HELP' >>>upper("help") Traceback (most recent call last): File "", line 1, in  NameError: name 'upper' is not defined 

La palabra clave aquí es método. Hay una ligera diferencia entre una función y un método.

Método

Es una función que se define en la clase del objeto dado. Por ejemplo:

 class Dog: def bark(self): print 'Woof woof!' rufus = Dog() rufus.bark() # called from the object 

Función

Una función es un procedimiento definido globalmente:

 def bark(): print 'Woof woof!' 

En cuanto a su pregunta sobre la función len , la función definida globalmente llama al método especial __len__ del objeto. Así que en este escenario, es un problema de legibilidad.

De lo contrario, los métodos son mejores cuando se aplican solo a ciertos objetos. Las funciones son mejores cuando se aplican a múltiples objetos. Por ejemplo, ¿cómo puedes escribir en mayúscula un número? No lo definirías como una función, solo lo definirías como un método solo en la clase de cadena.

Lo que usted llama “notación de puntos” son métodos de clase y solo funcionan para las clases que tienen el método definido por el implementador de la clase. len es una función incorporada que toma un argumento y devuelve el tamaño de ese objeto. Una clase puede implementar un método llamado len si quiere, pero la mayoría no lo hace. La función len incorporada tiene una regla que dice que si una clase tiene un método llamado __len__ , la usará, así que esto funciona:

 >>> class C(object): ... def __len__(self): ... return 100 ... >>> len(C()) 100 

"help".upper es lo contrario. La clase de cadena define un método llamado upper , pero eso no significa que tenga que haber una función llamada upper también. Resulta que hay una función upper en el módulo de string , pero en general no es necesario implementar una función adicional solo porque implementó un método de clase.

Esta es la diferencia entre una función y un método. Si solo está aprendiendo lo básico, tal vez simplemente acepte que esta diferencia existe y que eventualmente lo entenderá.

¿Aún aquí? Ni siquiera es difícil, en realidad. En la progtwigción orientada a objetos, los métodos se prefieren a las funciones para muchas cosas, porque eso significa que un tipo de objeto puede anular su versión del método sin afectar al rest del sistema.

Por ejemplo, supongamos que tienes un nuevo tipo de cadena donde los caracteres acentuados deberían perder su acento cuando llamas a .upper() . Las instancias de este tipo pueden subclasificar str y comportarse exactamente igual en todos los demás aspectos, básicamente de forma gratuita; todo lo que necesitan para redefinir es el método upper (e incluso entonces, probablemente llame al método de la clase base y solo cambie la lógica cuando maneje un carácter en minúscula acentuado). Y el software que espera trabajar en cadenas solo continuará funcionando y ni siquiera sabrá la diferencia si pasa un objeto de este nuevo tipo donde se espera una str estándar.

Un principio de diseño en Python es que todo es un objeto. Esto significa que puede crear sus propios reemplazos incluso para objetos fundamentales básicos como object , class y type , es decir, extender o anular el lenguaje básico para su aplicación o plataforma.

De hecho, esto sucedió en Python 2 cuando se introdujeron en el lenguaje cadenas de unicode . Una gran cantidad de software de aplicación continuó funcionando exactamente igual que antes, pero ahora con instancias de unicode donde anteriormente se había escrito el código para manejar las instancias de str . (Esta diferencia ya no existe en Python 3; o más bien, el tipo que fue llamado str y se usó en casi todas partes ahora se llama bytes y solo se usa cuando usted quiere manejar datos que no son texto).

Volviendo a nuestro nuevo método upper , piense en el caso opuesto; Si upper fuera solo una función en la biblioteca estándar, ¿cómo pensaría siquiera en modificar el software que necesita upper para comportarse de manera diferente? ¿Y si mañana tu jefe quiere que hagas lo mismo por lower ? Sería una tarea enorme, y los cambios que tendría que hacer en todo el código base tenderían fácilmente hacia una estructura de espaguetis, así como probablemente introducir nuevos errores sutiles.

Esta es una de las piedras angulares de la progtwigción orientada a objetos, pero es probable que solo sea realmente una enseñanza cuando aprendes los otros dos o tres principios en una introducción más estructurada. Por ahora, tal vez el resumen rápido y sucio sea “los métodos hacen que la implementación sea modular y extensible”.