Todo es Primera Clase
Uno de mis objetivos con Python era conseguir que todos los objetos lo fueran de pleno derecho, que todos los objetos fueran objetos de primera clase. Con esta expresión quiero decir que todos los objetos que pudieran ser nombrados en el lenguaje (Números enteros, cadenas de texto, funciones, clases, módulos, métodos, etc...) tuvieran el mismo estatus. Todos ellos podrían ser asignados a variables, colocados en listas, almacenados en diccionarios, pasados como argumentos, y así con todo.
La implementación interna de Python hacía que fuera fácil. Todos los objetos de Python están basados en una estructura de datos normal de C, que es usada en todas partes por el interprete. Variables, listas, funciones y todo lo demás son simplemente variaciones de esta estructura de datos. Sencillamente, no tenía la menor importancia para qué se usara la estructura, si para almacenar un sencillo objeto, como un número entero, o para algo más complicado, como una clase.
Aunque la idea de tener "objetos de primera clase para todo" era conceptualmente sencilla, aun había que lidiar con un problema insidioso de las clases que estaba por solucionarse: hacer que los métodos también fueran objetos de primera clase.
Consideremos esta sencilla clase de Python (Copiada de la entrada de la semana pasada):
class A:
def __init__(self,x):
self.x = x
def spam(self,y):
print self.x, y
Si los métodos fueran objetos de primera clase, podrían ser asignados a otras variables, usadas como cualquier otro tipo de objeto en Python. Por ejemplo, alguien podría escribir una sentencia como s = A.spam. En este caso, la variable s referenciaría a un método de una clase, que es en realidad sólo una función. Hay que aclarar, no obstante, que un método no es exactamente igual que una función normal. Concretamente, se espera que el primer argumento de un método sea una instancia de la clase en que está definido el método.
Para manejar esta situación, creé un tipo de objeto invocable conocido como método desligado (unbound method). Un método desligado es en realidad una delgada capa sobre el objeto función que implementa el método, que obliga a que se cumpla la restricción de que el primer argumento tenga que ser una instancia de la clase en la que está definido el método. De esta forma, si alguien llama a un método desligado s como si fuera una función, estaría obligado a incluir como primer argumento una instancia de la clase A. Por ejemplo :
a = A()
s(a)
Un problema similar ocurre si alguien escribe una sentencia que referencia a un método de una instancia específica de un objeto. Por ejemplo, alguien podría crear una instancia usando a = A(), y más tarde escribir una sentencia como s = a.spam. Aquí, la variable s se refiere de nuevo al método de la clase, pero la referencia al método se obtuvo a través de la instancia a. Para resolver este problema, se utiliza un objeto diferente, llamado método ligado (bound method). Es, al igual que el caso anterior, una delgada capa que recubre a la función objeto de un método. Este recubrimiento, sin embargo, almacena internamente el valor de la instacia original que se usó para obtener el método. De esta forma, una llamada posterior a s() llamara al método usando implícitamente la instancia a como primer argumento.
En realidad, internamente se usa el mismo tipo de objeto para representar métodos ligados o desligados. Uno de los atributos que tiene esta objeto es una referencia a una instancia. Si esta referencia es None, entonces el método está desligado; en caso contrario, está ligado.
Aunque este tema de los métodos ligados y desligado puede parecer un detalle sin importancia, son una parte crítica del mecanismo interno de las clases. Cuando aparece una sentencia como a.spam() en un programa, la ejecución de la misma sucede en dos fases. Primero hay una búsqueda de a.spam. Esta búsqueda devuelve un método ligado, un objeto que es invocable. A continuación, se aplica la operación de llamada () al objeto para invocar al método definido por el usuario, con los argumentos correspondientes.
Añadir un comentario