Tipos de datos en Python3

En los lenguajes de programación la forma en la cual se representan datos es a través de los tipos de datos, que indican si una variable es un entero, una cadena, etc. Python es un lenguaje de programación dinámico, eso quiere decir que no hay tipado estático, una variable en el tiempo de ejecución –cuando el programa está corriendo, puede ser cambiada sin problema alguno, a diferencia de lenguajes como C, que si la variable es declarada en un tipo en específico, la referencia se mantiene y el compilador sabe que tipo de dato tomará.

Python aporta mecanismos de deducción al igual que Javascript, que permiten saber que tipo de dato es una variable, cuando el script se encuentra en ejecución.

La forma de declarar una variable es la siguiente: =

El nombre de la variable debe tener los siguientes atributos:

  1. No puede iniciar con un número.
  2. Puede contener caracteres alfanuméricos en mayúsculas y minúsculas.
  3. Puede contener underscore (_).
  4. Puede contener números al final.

En lo personal hago uso de nombres expresivos para las variables, sin necesidad que se tenga que comentar demás, por ejemplo si tengo un manejador de stream, en inglés el nombre sería stream_handler.


#se obtiene el manejador actual del stream en base a la url del recurso actual
stream_handler = stream.get_current_handler(resource_uri)

Para poner un comentario de una sola línea se hace uso del carácter (#) ,  y si es de múltiples líneas se hace uso de comillas triples (»’); mis reglas para hacer uso del lenguaje en cuestión de variables son las siguientes:

  1. No declarar una variable si solamente va a ser usada una vez.
  2. Usar nombres expresivos, que no sean demasiado largos, y en caso de que sean largos usar abreviaciones por ejemplo temporary_file sería tmp_file.
  3. Usar una variable para un tipo específico, para evitar la inferencia por parte del intérprete y ahorrar tiempo de ejecución.

En python existen distintos tipos de datos como los Nativos y las Estructuras de Datos, los tipos Nativos es la representación por parte del lenguaje para cadenas, números, números flotantes –con decimales en la mantisa, boleanos (sus posibles valores son verdadero y falso) y las estructuras de datos que sirven para almacenar múltiples datos nativos a través de conjuntos, tuplas o listas y diccionarios, tal como se puede ver en la siguiente imagen.

52a258ce-3059-4e8d-a527-9d98ab2afede
Jerarquía de los tipos de datos en Python

Tipos de datos en Python3

  • Numéricos
    • Enteros
    • Reales
    • Imaginarios
  • Cadenas
    • Byte
    • ByteArray
  • Boleanos

Solamente en este artículo se verán los tipos de datos nativos, que son a través de los cuales se compone el lenguaje.

Tipos de datos numéricos

Enteros

Los números enteros en el lenguaje son una representación en base 10, estos pueden ser positivos y negativos, incluyendo el número neutro [0], en base a sus representaciones binarias, para más información leer sobre complemento a 2, 1 y números positivos binarios.

La declaración de una variable entera, se hace de la siguiente manera:


#se declara una variable entera que es igual a 97 en representación base 10

my_int_var = 97

print(my_int_var) #97

Lo que molesta a muchos programadores que vienen de lenguajes como C++ o Java es que Python hace uso de tabulaciones para definir que una instrucción pertenece a un bloque.

Al igual que otros lenguajes Python trabaja con varias representaciones numéricas, se pueden representar valores hexadecimales, octales y binarios


#representación de un 97 en base 10

my_int_var = 97

print(my_int_var)

#representación de un 97 en hexadecimal

my_int_var = 0x61

print(my_int_var) #97

#representación de un 97 en binario

my_int_var = 0b01100001

print(my_int_var) #97

#representación de un 97 en octal

my_int_var = 0o141

print(my_int_var) #97

Tal como se puede ver se emplea esta notación para propósitos muy específicos, que se pueden usar en muchas aplicaciones, por ejemplo mediante un programa de ingeniería inversa leer las direcciones en la que escribe cierto proceso que serían representadas en un rango.

Reales

Los números reales se representan mediante un número entero y una mantisa que es la parte decimal, las cuales se encuentran separadas por un punto (.), estos números se utilizan para hacer operaciones de gran precisión como calcular el clima, o la órbita de un satélite alrededor de la tierra.


my_real = 4.23567889456

print(my_real) #4.23567889456

#también se puede usar la notación exponencial ax10^n
increase_rate = 8.32e-32 #8x10⁻³²

print(increase_rate) #8.32e-32

Imaginarios

Los números imaginarios representan un sistema numérico fuera de los reales y enteros es decir, que con estos se puede formar un algebra, por lo tanto un número imaginario está conformada por una parte entera y otra imaginaria, Z=a+jb, en donde j es igual a la raiz cuadrada de -1, gracias a este tipo de números se pueden transformar y representar entidades que en un plano real no podrían se resueltas o resultan imposibles.


#un número imaginario se representa mediante la parte real e imaginaria

z=8+4j

print(z) #8+4j1

Cadenas

Las cadenas son un conjunto de uno o más caracteres,  y un caracter es una representación numérica para un símbolo, por ejemplo en ASCII —para los que tienen linux introduzcan el comando man ascii, una letra a minúscula es un 97 que sería en binario un 01100001.

Las cadenas desde Python3 están codificadas en formato Unicode, anteriormente se encontraban codificadas en ASCII, desde mi punto de vista se hizo el cambio porque soporta más símbolos, para ser exacto más de 120,000 y también por cuestiones de rendimiento.


#la forma de definir una cadena en python es usando las comillas simples

name = "Bob"

print(name) #bob

Ya que una cadena es un conjunto de caracteres entonces se puede iterar usando un ciclo for, para los que recién inician a ver un lenguaje pueden saltar esta parte.


message = "hello"

#se itera una cadena a través de un ciclo for usando la palabra
#reservada in que permite obtener el caracter actual, esto es
#porque se implementa un iterador de forma implícita
for word in message:

print(word)

#porque una cadena contiene un iterador de forma implícita se puede acceder a sus componentes
print(message[0]) #h

En python existen dos tipos de cadenas mutables e inmutables, las del primer tipo tal como su nombre lo dice, no se pueden cambiar y de forma contraria en las del segundo tipo.

Las cadenas inmutables son del tipo byte y se declaran escribiendo una b antes de escribir la cadena, este tipo de cadenas se utilizan para leer flujos de datos que ya no van a ser cambiados, por ejemplo obtener el estado de una red inalámbrica, leer datos de un stream UDP, etc.


my_string = b"this is one unmutable string"

#si se intenta mutar la cadena arroja un error

my_string[0] = "z" #error

#se puede obtener el tipo de la cadena

type(my_string) #byte

Para transformar una cadena Unicode a una cadena tipo Byte se utilizan los siguientes métodos:

  1. encode: codifica una cadena mutable a una cadena inmutable.
  2. decode: transforma una cadena inmutable a una mutable, obviamente las referencias de las dos cadenas serán diferentes.

#se obtiene el manejador actual del stream de datos

stream_handler  = stream.get_current_handler()

#obtiene los bytes del manejador actual

stream_bytes = stream_handler.get_bytes(4096)

#hace un fork con un conjunto de procesos que tratan los bytes de datos recibidos

fowarder(stream_bytes)

#imprime los datos que están siento tratados actualmente, transforma el tipo byte a cadena en formato unicode

server.log_data(stream_bytes.decode())

Cuando se le quiere aplicar una codificación específica como utf-8, utf-16, latin, latin1, etc a una cadena se hace uso de la función de la librería estándar bytearray.


#codificar una cadena en formato latin 1

my_string = bytearray("Hola cómo estás?", "latin1");

print(my_string) #imprime la cadena en un formato

Tipos de datos boleanos

Es un tipo de dato especial que solamente puede almacenar valores verdadero (True) y falso (False), se usan generalmente para indicar estados en un programa, validación, etc.


valid_request = False

print(valid_request) #False

Casteo de tipos

Se puede hacer un casteo usando los constructores o palabras reservadas, como las siguientes:

  • int: se refiere a un entero.
  • str: se refiere a una cadena.
  • byte: se refiere a un tipo byte.
  • float: se refiere a un tipo de número real.
  • bytearray: se refiere un arreglo de bytes.
  • complex: se refiere a un número complejo.
  • bool: se refiere a un tipo boleano.

Todos los tipos de datos son compatibles con cadenas es decir que si se tiene una cadena introducida por el usuario como un «2» se puede convertir a un entero de la siguiente forma.


#dato leido de una caja de texto

user_score = "2"

user_score = int(user_score) #castea de string a entero

print(type(user_score)) #int

Transparencia referencial

Existen dos conceptos muy importantes para comprender el manejo de los tipos de datos en un lenguaje de programación:

  1. Referencia: Indica en que dirección está almacenada el contenido de la variable.
  2. Valor: Es la representación del contenido de una variable en memoria.

Python maneja las referencias de forma implícita es decir que no se manejan en el lenguaje, además no aporta operadores y lógica para punteros, pienso que es para que se conserve la simplicidad en el mismo, carece de sobrecarga de operadores que solamente C maneja, para que dependiendo el tipo un operador se pueda comportar de forma diferente, en fin veamos como hace uso el lenguaje de las referencias.

Supongamos que tenemos una arquitectura con referencias de 32 bits, sean 0xab0cf2de0xab0cf2de las referencias en memoria en donde las variables X,Y se encuentran, entonces tenemos dos números enteros, en este caso 5 y 6, los cuales serán usados en los siguientes ejemplos.

Referencias


X=5
Y=6

#calcula el área de un triángulo donde X es la base y Y es la altura
area = (X*Y)/2

#¿Qué pasa si se hacen los siguientes cambios?
X=Y
X=2

print(X) #2
print(Y) #6

Especialmente en los tipos de datos nativos se almacenan únicamente los valores, en la operación en donde X=Y, se pasa el valor de Y que es 6 a X, pero después se cambia el valor de X a 2, si se pasara la referencia, entonces Y valdría 2, al imprimir el código no es así, por lo cual se concluye que los tipos nativos solamente almacenan los valores y tienen una representación especial en el lenguaje.

Deja un comentario