Los punteros en python son un concepto desconocido. Python no habla de punteros en ningún sentido. La razón es desconocida para nosotros y muchas personas por ahí. Si dice adivinar, podríamos decirlo porque los punteros son un arte difícil de aprender y Python es justo lo contrario.
El mecanismo de python es exactamente como pasar punteros por el valor en C. Pythons moto es por simplicidad y no por velocidad. Pero eso no significa que no podamos implementar punteros y en python se puede hacer a través de objetos. Ahora entendamos un poco sobre python.
Lea también: ¿Vale la pena aprender Python en el año 2021?
¿Qué son los punteros?
Un puntero es una variable que almacena otras direcciones de variables. Los punteros se utilizan para almacenar las direcciones de otras variables o elementos de memoria. Es un tipo de datos que almacena la dirección de otros tipos de datos. Si está familiarizado con C o C++entonces, ¿está familiarizado con lo que son los punteros?
Cada vez que creamos una variable o un objeto en un lenguaje de programación, se almacena en una dirección de CPU particular. Cada vez que enviamos los datos, se extrae de esa dirección. **Los punteros se utilizan para almacenar las direcciones y para la gestión de la memoria. Pero, a veces, los punteros pueden bloquear nuestros programas. Entremos en los detalles.
Qué es Pitón?
Python es un lenguaje de programación de alto nivel interpretado, orientado a objetos y con semántica dinámica. Sus estructuras de datos integradas de alto nivel, combinadas con la escritura dinámica y el enlace dinámico, lo hacen muy atractivo para el desarrollo rápido de aplicaciones. Así como para su uso como lenguaje de secuencias de comandos o pegamento para conectar componentes existentes entre sí. La sintaxis simple y fácil de aprender de Python enfatiza la legibilidad y, por lo tanto, reduce el costo de mantenimiento del programa. Python admite módulos y paquetes, lo que fomenta la modularidad del programa y la reutilización del código.
Características:
- Código abierto y gratuito
- Soporte para GUI
- Orientado a objetos Acercarse
- Lenguaje de alto nivel
- Integrado por la Naturaleza
- Altamente portátil
- Altamente Dinámica
¿Qué son los Objetos?
Ahora todo lo que hacemos en Python está basado en objetos. Y si te encuentras aquí y eres nuevo en esto, déjanos darte algunos ejemplos para mostrarte cómo es cierto.
## int print(f'int:- {isinstance(int, object)}') ## str print(f'str:- {isinstance(str, object)}') ## bool print(f'bool:- {isinstance(False, object)}') ## list print(f'list:- {isinstance(list(), object)}') ## function def sample(): pass print(f'function:- {isinstance(sample, object)}')
int:- True str:- True bool:- True list:- True function:- True
Ahora como ya te dijimos, puedes verlo por ti mismo. Todo en Python es objeto. Cada objeto en Python consta de 3 partes
En primer lugar: Tipo
Se refiere al tipo de objeto como int, float, string, etc.
En segundo lugar: Valor
Es el valor real de un objeto almacenado en la memoria.
Por último: Recuento de referencia
Se trata de la memoria en la CPU. Representa el número de variables de Python que se refieren a una ubicación de memoria.
Los tipos de datos de objetos son de dos tipos. Inmutable y Mudable. Y saber si los objetos son inmutables y mutables es nuestro paso hacia el aprendizaje de punteros:
¿Qué son los objetos inmutables?
Los objetos inmutables son aquellos objetos que no se pueden cambiar una vez creados. La mayoría de los tipos de datos comúnmente utilizados en Python son inmutable. Veamos qué significa eso. Podemos probar objetos inmutables por id() y es,
- identificación(): devuelve la dirección de memoria del objeto.
- es: comprueba si dos objetos tienen la misma dirección de memoria o no.
int() es un objeto inmutable, déjanos mostrarte con un ejemplo:
a = 7 id(a)
1744268544
En esto puedes ver que hemos asignado el valor de 7 a a. Ahora no podemos modificar el valor de X en 1744268544 memoria. Si tratamos de cambiarlo, creará un nuevo objeto. Pero podemos agregar un 1 a un luego veamos su dirección nuevamente.
a += 1 id(a)
1744268576
La dirección de a ahora ha cambiado y esto significa que el objeto que creamos ahora se refiere a la nueva dirección.
b = a b is a
True
Ahora, cuando asignamos a = b, python no crea nuevos objetos, solo hace una referencia de a a b al hacerlo, ahorra memoria.
¿Qué son los objetos mutables?
Puede cambiar un objeto mutable incluso después de haberlo creado. Python no crea un nuevo objeto cuando cambia un objeto mutable. Vamos a un ejemplo para una mayor comprensión:
## list is a mutable object nums = [1, 2, 3, 4, 5] print("---------Before Modifying------------") print(id(nums)) print() ## modifying element nums[0] += 1 print("-----------After Modifying Element-------------") print(id(nums)) print() ## appending an element nums.append(6) print("-----------After Appending Element-------------") print(id(nums))
---------Before Modifying------------ 2197288429320 -----------After Modifying Element------------- 2197288429320 -----------After Appending Element------------- 2197288429320
Como puede ver, incluso después de realizar varias funciones en la lista, la dirección no cambia. Porque la lista es un objeto mutable. Lo mismo ocurre cuando realizamos otras mudable objetos como set o dict.
Un poco sobre el modelo de objetos de Python:
Las variables funcionan de manera diferente en Python que en C. Entonces, primero debemos aprender cómo funcionan las variables en C para tener una mejor comprensión de todo.
Variables C:
Entonces, echemos un vistazo a cómo se ejecutan las variables en C, que es diferente de Python.
// C syntax not Python int a = 918
Ahora debemos explicar cuáles son estas sintaxis en la programación anterior:
- Asigna memoria para el entero.
- Asigna un valor a la variable. a.
- Marcas a hacer referencia al valor de 918.
Si ilustramos la memoria, puede quedar como la siguiente.
Entonces, aquí puedes ver que a tiene una ubicación de memoria de 0x531. Si actualizamos el valor de a. La ubicación de la dirección de a no cambia
a = 849
Entonces, si ve que la ubicación de a no cambia en el lenguaje de programación C. La variable simplemente no es el nombre de los valores, es una ubicación de memoria en sí misma.
Ahora, si asignamos una nueva variable a Python, a diferencia de Python, C crea una nueva ubicación de memoria. El siguiente código asigna a a una nueva variable **b.
int b = a
Ahora puede ver que la dirección de b ha cambiado. Porque C crea una nueva ubicación para cada objeto que creamos. Después de la variable C, ahora vayamos a python nuevamente.
Ahora los nombres de Python:
Puede llamar variables en python como nombres.
## code in python a = 918
El código anterior pasará por las siguientes cosas:
- Crea un nuevo PyObject.
- Establece el tipo de datos como un número entero para PyObject.
- Establece el valor 918 en PyObject.
- Crea un nombre como definimos (a).
- Apunta a PyObject.
- Incrementa el recuento de referencias de PyObject de 0 a 1.
a ilustración de ubicación de memoria de referencia
Aquí a se refiere al pyobject en la memoria. Esto es completamente diferente de las variables en C. a no es una ubicación de memoria como lo era en las variables C.
a = 87
La declaración anterior se somete a los siguientes pasos durante la ejecución.
- Crea un nuevo PyObject.
- Establece el tipo de datos como un número entero para PyObject.
- Establece el valor 98 en PyObject.
- Apunta al nuevo PyObject.
- Incrementa el Refer Count del nuevo PyObject en 1.
- Disminuye el Recuento de referencias del antiguo PyObject en 1.
Ahora con falsos punteros en Python
Como ya hemos discutido, los punteros en python no estaban incluidos. Pero aún así, si lo desea, puede usar punteros en python usando varios métodos diferentes.
Ahora vamos a escribir un programa corto simple para ayudarte a entender esto un poco mejor.
// C code void increment(int *p) { *p += 1; }
Como puede ver aquí, la función de incremento toma un puntero y puede usar el valor refiriéndose a otra variable de puntero.
// C code main function void main() { int a = 759; printf("%d\n", a); increment(&a);//& operator used to extract the address of the variable printf("%d\n", a); }
// Output 759 769
Ahora vamos a usar esta misma función en el objeto mutable.
Objetos mutables:
Entonces, ahora podemos ejecutar todo el programa anterior en python usando objetos mutables.
## function def increment(p): p[0] += 1 if __name__ == "__main__": a = [759] increment(a) print(a[0])
760
Como puede ver, hemos logrado el mismo resultado también a través de python. La función toma un incremento en la lista y luego incrementa los primeros elementos. Si intentamos pasar una tupla como argumento a la función **incremento, obtendremos un error. Entonces aparecerá el siguiente error como puede a continuación:
if __name__ == "__main__": a = (759,) increment(a) print(a[0])
TypeError Traceback (most recent call last) <ipython-input-32-c3bce5df94da> in <module>() 1 if __name__ == "__main__": 2 a = (759,) ----> 3 increment(a) 4 print(a[0]) <ipython-input-30-042f4c577fd9> in increment(p) 1 ## function 2 def increment(p): ----> 3 p[0] += 1 4 5 if __name__ == "__main__": TypeError: 'tuple' object does not support item assignment
Ahora hablaremos de Punteros en Ctype:
Entonces, al usar los ctypes, podemos crear punteros en python. Lo primero que haremos será compilar un .C archivo que contiene funciones que usan punteros y lo almacenan. Ahora vamos a escribirlo juntos.
void increment(int *p) { *p += 3; }
Simplemente asuma que el nombre del archivo es incre.c y ahora puede ejecutar el siguiente comando:
$ gcc -c -Wall -Werror -fpic incre.c
$ gcc -shared -o libinc.so incre.o
Entonces, como puede ver, incre.c compila el objeto en incre.o. Y ahora el segundo objeto crea otro archivo de objeto y produce libinc.so trabajar con ctipos.
import ctypes ## make sure the libinc.so present in the same directory as this program lib = ctypes.CDLL("./libinc.so") lib.increment
## output <_FuncPtr object at 0x7f46bf6e0750>
inc = lib.increment ## defining the argtypes inc.argtypes = [ctypes.POINTER(ctypes.c_int)]
inc(10)
## output Traceback (most recent call last): File "<stdin>", line 1, in <module> ctypes.ArgumentError: argument 1: <class 'TypeError'>: expected LP_c_int instance instead of int
Ahora tenemos un error que dice que la función quiere un puntero.
a = ctypes.c_int(10)
Entonces puedes ver que una variable es C. ctipos tiene un método llamado porref() que le permite pasar la referencia variable.
inc(ctypes.byref(a)) a
## output c_int(11)
Ahora como puede, el valor de a se ha incrementado.
Conclusión:
Por lo tanto, los punteros en python eran un mito cuando comenzó este blog y ahora los hemos abordado por completo, ahora les hemos dado ejemplos de cómo ejecutar punteros con C en python. Esperamos que esta información sea útil. Gracias por la lectura.