de datos básicos
Aquello a lo que llamamos tipos de datos básicos no es más que el conjunto de los principales tipos integrados. Estos pueden ser agrupados en cuatro categorías:
• números: enteros (tipo int), booleanos (bool), complejos (complex), de punto flotante (float);
• conjuntos: representados por el tipo set;
• secuencias: cadenas (str y byte), listas (list) y tuplas (tuple);
• diccionarios: representados por el tipo dict.
Los tipos de datos básicos pertenecen a una categoría de objetos llamados clases, o también tipos. La carácterística de los tipos, como su nombre indica, es la de representar un tipo de dato genérico, a partir del cual podamos crear objetos específicos de dicho tipo, llamados instancias. Por ejemplo, a partir del tipo str podemos crear las instancias "python", "Guido" y"abc"; a partir del tipo int las instancias 22 y 77; a partir del tipo list las instancias [1, 2, 3] y ['a', 'b', 'c', 'd'], y así para el resto de tipos. Por lo tanto, diremos que una cadena de texto es un objeto de tipo str, o, lo que es lo mismo, que es una instancia del tipo str. Del mismo modo, diremos que un entero es un objeto del tipo int, o, lo que es lo mismo, una instancia del tipo int, y así para los números de punto flotante, las listas, etc.
Algunos objetos son fáciles de imaginar debido a que tienen muy en cuenta tanto el concepto de valor como el de tipo, como en el caso de las instancias de los tipos numéricos:
Su tipo, como el de cualquier otro objeto, puede obtenerse a partir de la clase integrada type:
Los objetos están siempre carácterizados por un tipo, mientras que solo a alguno de ellos podemos asociarle de manera intuitiva un valor. Además del tipo, otros elementos carácterísticos de los objetos son la identidad y los atributos.
La identidad está representada por un número que los identifica de manera única, y es devuelta por la función integrada id():
Los atributos son identificadores accesibles mediante el delimitador punto:
En este ejemplo bit_length, as_integer_ratio e imag son atributos, respectivamente, de a, b y c. Los atributos están estrechamente vinculados al tipo de un objeto. Por ejemplo, todos los objetos de tipo str tienen el atributo str.upper(), el cual devuelve una versión de la cadena en mayúsculas:
y todos los objetos de tipo list tienen el atributo list.sort() que reordena los elementos de la lista:
Cuando a un identificador le siguen unos paréntesis (), se dice que el objeto al cual hace referencia es llamable (callable). Al aplicar los paréntesis al identificador, decimos que estamos llamando al objeto. Consideremos, por ejemplo, un número complejo:
Todos los números complejos tienen el siguiente atributo:
y este es llamable. Cuando lo llamamos, nos devuelve el complejo conjugado del número:
Podemos descubrir si un objeto es llamable gracias a la función integrada callable():
Si intentamos llamar a un objeto que no es llamable, obtenemos un error:
Los objetos llamables se distinguen de los que no lo son por el hecho de que permiten ejecutar una serie de operaciones, o bien un bloque de instrucciones. Las funciones, por ejemplo, son objetos llamables. Para aclarar mejor este concepto, consideremos la función integrada sum:
esta es un objeto llamable:
y si la llamamos, ejecuta la suma de los elementos del objeto que pasamos como argumento:
Si en una llamada no debemos pasar ningún argumento, igualmente utilizaremos los paréntesis:
Los parentesis, de hecho, indican que queremos ejecutar las operaciones que pertenecen al objeto llamable.
Los atributos llamables se denominan métodos. Según cuanto hemos dicho hasta ahora, la diferencia entre los métodos y los otros atributos es que los primeros pueden ser llamados para ejecutar operaciones, mientras que los segundos no. Consideremos de nuevo el número complejo c = 1 + 2j:
Sus atributos c.real y c.imag no son métodos y, por tanto, no pueden ser llamados. En cambio, el atributo c.conjugate es un método y al ser llamado ejecuta la operación c.real - c.imag y devuelve el resultado:
NOTA
En este libro, cuando en el texto escribamos el identificador de un método o de una función, utilizaremos los paréntesis. Por ejemplo, escribiremos c.conjugate() e id() y no c.conjugate e id para indicar el método coniugate() de los números complejos y la función integrada id(). En cambio, cuando hablemos de las clases, aunque son objetos llamables, no utilizaremos los paréntesis, por lo que escribiremos, por ejemplo, type y no type(). En el Capítulo 6, cuando hablemos del modelo a objetos de Python y de las meta-clases, entenderemos por qué tiene sentido la distinción entre objetos que son clases y objetos que no lo son.
Sustancialmente, los métodos son funciones y, de hecho, son definidos como tales, como veremos en la sección Definir las clases.
Si estos conceptos os parecen demasiado abstractos, no os preocupéis, puesto que los retomaremos más de una vez en este libro y los afrontaremos de manera exhaustiva en el Capítulo 5, cuando presentemos la programación orientada a objetos y veamos en detalle los distintos tipos de método.
La función integrada dir() devuelve una lista de los nombres de los atributos más significativos de un objeto:
Todos los atributos que empiezan y terminan con un doble guion bajo se denominan atributos especiales o también atributos mágicos. Veremos el significado de alguno de ellos en este capítulo y en los dos siguientes, mientras que del resto hablaremos de forma más profunda en el Capítulo 6.
La función integrada hasattr() nos dice si un objeto tiene cierto atributo: