En este tutorial, aprenderemos sobre los punteros en Python y veremos por qué Python no admite conceptos de punteros.
También entenderemos cómo podemos simular el puntero en Python. A continuación se muestra la introducción del puntero para aquellos que no tienen ninguno al respecto.
También entenderemos cómo podemos simular el puntero en Python. A continuación se muestra la introducción del puntero para aquellos que no tienen ninguno al respecto.
¿Qué es el puntero?
Pointer es una herramienta muy popular y útil para almacenar la dirección de la variable. Si alguien alguna vez ha trabajado con un lenguaje de bajo nivel como C . C++ , probablemente esté familiarizado con los consejos. Gestiona el código de manera muy eficiente. Puede resultar un poco difícil para los principiantes, pero es uno de los conceptos importantes del programa. Sin embargo, puede provocar varios errores de gestión de la memoria. Por lo tanto, la definición de punteros -
'Los punteros son las variables que contienen la dirección de memoria de otra variable. Las variables de puntero están representadas por un asterisco (*).
Veamos el siguiente ejemplo del puntero en lenguaje de programación C.
Ejemplo: cómo utilizar el puntero en C
#include int main() { int* po, o; 0 = 10; printf('Address of c: %p ', &c); printf('Value of c: %d ', c); o = &0; printf('Address of pointer pc: %p ', o); printf('Content of pointer pc: %d ', *o); 0 = 11; printf('Address of pointer pc: %p ', p0); printf('Content of pointer pc: %d ', *p0); *po = 2; printf('Address of c: %p ', &o); printf('Value of c: %d ', o); return 0; }
Producción:
Address of o: 2686784 Value of o: 22 Address of pointer po: 2686784 Content of pointer po: 22 Address of pointer po: 2686784 Content of pointer po: 11 Address of o: 2686784 Value of o: 2
Además de ser útiles, los punteros no se utilizan en Pitón . En este tema, analizaremos el modelo de objetos de Python y aprenderemos por qué no existen los punteros en Python. También aprenderemos diferentes formas de simular punteros en Python. Primero, analicemos por qué Python no admite punteros.
¿Por qué Python no admite punteros?
La razón exacta por la que no se admite el puntero no está clara. ¿Podría existir un puntero en Python de forma nativa? El concepto principal de Python es su simplicidad, pero el puntero viola el Zen de Pitón. Se fomentan principalmente los cambios implícitos en lugar de los explícitos. También son complejos, especialmente para principiantes.
Los punteros tienden a crear complejidad en el código, donde Python se centra principalmente en la usabilidad más que en la velocidad. Como resultado, Python no admite punteros. Sin embargo, Python ofrece algunos beneficios al usar el puntero.
Antes de comprender el puntero en Python, debemos tener una idea básica de los siguientes puntos.
- Objetos inmutables versus mutables
- Variables/nombres de Python
Objetos en Python
En Python, todo es un objeto, incluso clases, funciones, variables, etc. Cada objeto contiene al menos tres datos.
ajuste de palabras css
- Recuento de referencias
- Tipo
- Valor
Discutamos uno por uno.
Recuento de referencias - Se utiliza para la gestión de la memoria. Para obtener más información sobre la administración de memoria de Python, lea Administración de memoria en Python.
Tipo - El CPython La capa se utiliza como tipo para garantizar la seguridad del tipo durante el tiempo de ejecución. Finalmente, hay un valor, que es el valor real asociado con el objeto.
Sin embargo, si profundizamos en este objeto, encontraremos que no todos los objetos son iguales. La distinción importante entre los tipos de objetos es inmutable y mutable. En primer lugar, debemos comprender la diferencia entre los tipos de objetos porque explora el puntero en Python.
Objetos inmutables frente a objetos mutables
Los objetos inmutables no se pueden modificar, mientras que los objetos mutables sí se pueden modificar. Veamos la siguiente tabla de tipos comunes y si son mutables o no.
Objetos | Tipo |
---|---|
En t | Inmutable |
Flotar | Inmutable |
booleano | Inmutable |
Lista | Mudable |
Colocar | Mudable |
Complejo | Mudable |
tupla | Inmutable |
conjunto congelado | Inmutable |
dictar | Mudable |
Podemos verificar el tipo de los objetos anteriores usando el identificación() método. Este método devuelve la dirección de memoria del objeto.
Estamos escribiendo las siguientes líneas en un entorno REPL.
x = 5 id(x)
Producción:
140720979625920
En el código anterior, le hemos asignado el valor 10 a x. si modificáramos este valor con sustitución, obtendríamos los nuevos objetos.
x-=1 id(x)
Producción:
140720979625888
Como podemos ver, modificamos el código anterior y obtenemos nuevos objetos como respuesta. Tomemos otro ejemplo de cadena .
s = 'java' print(id(s)) s += 'Tpoint' print(s) id(s)
Producción:
2315970974512 JavaTpoint 1977728175088
Nuevamente, modificamos el valor de x agregando una nueva cadena y obtenemos la nueva dirección de memoria. Intentemos agregar una cadena directamente en s.
s = 'java' s[0] = T print(id(s))
Producción:
Traceback (most recent call last): File 'C:/Users/DEVANSH SHARMA/PycharmProjects/MyPythonProject/python1.py', line 34, in s[0] = T NameError: name 'T' is not defined
El código anterior devuelve un error, significa que la cadena no admite la mutación. Entonces cadena Son los objetos inmutables.
Ahora veremos el objeto mutable como la lista.
my_list = [3, 4, 8] print(id(my_list)) my_list.append(4) print(my_list) print(id(my_list))
Producción:
convertir cadena a entero
2571132658944 [3, 4, 8, 4] 2571132658944
Como podemos ver en el código anterior, el mi lista tiene la identificación originalmente y le hemos agregado 5 a la lista; mi lista tiene la misma identificación porque la lista admite la mutabilidad.
Comprender las variables de Python
La forma de definir variables en Python es muy diferente a la de C o C++. La variable de Python no define el tipo de datos. De hecho, Python tiene nombres, no variables.
Por lo tanto, debemos comprender la diferencia entre variables y nombres, y esto es especialmente cierto cuando navegamos por el complicado tema de los punteros en Python.
Entendamos cómo funciona la variable en C y cómo funciona el nombre en Python.
Variables en C
En lenguaje C, una variable es aquello que contiene valor o almacena valor. Se define con el tipo de datos. Veamos el siguiente código que define la variable.
int x = 286;
- Asigne suficiente memoria para un número entero.
- Asignamos el valor 286 a esa ubicación de memoria.
- La x representa ese valor.
Si representamos la visión de la memoria -
Como podemos ver, la x tiene una ubicación de memoria para el valor 286. Ahora, asignaremos el nuevo valor a x.
x = 250
Este nuevo valor sobrescribe el valor anterior. Significa que la variable x es mutable.
La ubicación del valor de x es la misma, pero el valor cambió. Es un punto importante que indica que x es la ubicación de la memoria, no sólo su nombre.
Ahora, introducimos la nueva variable que toma la x, luego la y crea el nuevo cuadro de memoria.
int y = x;
La variable y crea un nuevo cuadro llamado y copia el valor de x en el cuadro.
Nombres en Python
Como comentamos anteriormente, Python no tiene variables. Tiene nombres y usamos este término como variable. Pero hay una diferencia entre variables y nombres. Veamos el siguiente ejemplo.
x = 289
El código anterior se desglosa durante la ejecución.
- Crear un PyObjeto
- Establezca el código de tipo en número entero para PyObject
- Establezca el valor en 289 para PyObject.
- Crea un nombre llamado x
- Apunte x al nuevo PyObject
- Aumentar el recuento del PyObject en 1
Se verá como se muestra a continuación.
Podemos comprender el funcionamiento interno de una variable en Python. La variable x apunta a la referencia del objeto y no tiene el espacio de memoria como antes. También muestra que x = 289 está vinculando el nombre x a una referencia.
función de llamada javascript desde html
Ahora, introducimos una nueva variable y le asignamos x.
y = x
En Python, la variable y no creará el nuevo objeto; es sólo un nuevo nombre que apunta al mismo objeto. El objeto recuento también aumentó en uno. Podemos confirmarlo de la siguiente manera.
y is x
Producción:
True
Si aumentamos el valor de y en uno, ya no hará referencia al mismo objeto.
y + =1 y is x
Eso significa que en Python no asignamos variables. En cambio, vinculamos nombres a referencias.
Simulando punteros en Python
Como hemos comentado, Python no admite punteros, pero podemos obtener los beneficios de utilizar un puntero. Python proporciona formas alternativas de utilizar el puntero en Python. Estas dos formas se detallan a continuación.
- Usar tipos mutables como punteros
- Usando objetos Python personalizados
Entendamos los puntos dados.
Usar tipos mutables como puntero
En la sección anterior, hemos definido los objetos de tipo mutable; podemos tratarlos como si fueran punteros para simular el comportamiento del puntero. Entendamos el siguiente ejemplo.
C
void add_one(int *a) { *a += 1; }
En el código anterior, definimos el puntero *a, luego incrementamos el valor en uno. Ahora lo implementaremos con la función main().
instalación experta
#include int main(void) { int y = 233; printf('y = %d ', y); add_one(&y); printf('y = %d ', y); return 0; }
Producción:
y = 233 y = 234
Podemos simular este tipo de comportamiento utilizando el tipo mutable de Python. Comprenda el siguiente ejemplo.
def add_one(x): x[0] += 1 y = [2337] add_one(y) y[0]
La función anterior accede al primer elemento de la lista e incrementa su valor en uno. Cuando ejecutamos el programa anterior, imprime el valor modificado de y. Significa que podemos replicar el puntero usando el objeto mutable. Pero si intentamos simular un puntero usando un objeto inmutable.
z = (2337,) add_one(z)
Producción:
Traceback (most recent call last): File '', line 1, in File '', line 2, in add_one TypeError: 'tuple' object does not support item assignment
Usamos la tupla en el código anterior, un objeto inmutable, por lo que devolvió el error. También podemos usar el diccionario para simular el puntero en Python.
Entendamos el siguiente ejemplo donde contaremos cada operación que ocurre en el programa. Podemos usar dict para lograr esto.
Ejemplo -
count = {'funcCalls': 0} def car(): count['funcCalls'] += 1 def foo(): count['funCcalls'] += 1 car() foo() count['funcCalls']
Producción:
2
Explicación -
En el ejemplo anterior, hemos utilizado el contar diccionario, que realizaba un seguimiento del número de llamadas a funciones. Cuando el foo() Se llama a la función, el contador aumenta 2 porque dict es mutable.
Usando objetos de Python
En el ejemplo anterior, utilizamos dict para emular el puntero en Python, pero a veces resulta difícil recordar todos los nombres de clave utilizados. Podemos usar la clase personalizada de Python en lugar del diccionario. Entendamos el siguiente ejemplo.
Ejemplo -
class Pointer(object): def __init__(self): self._metrics = { 'funCalls': 0, 'catPictures': 0, }
En el código anterior, hemos definido la clase Puntero. Esta clase usó dict para contener datos reales en la variable miembro _metrics. Proporcionará mutabilidad a nuestro programa. Podemos hacer esto de la siguiente manera.
class Pointer(object): # ... @property def funCalls(self): return self._metrics['func_calls'] @property def catPictures_served(self): return self._metrics['cat_pictures_served']
Hemos usado @propiedad decorador. Si no está familiarizado con los decoradores, visite nuestro tutorial sobre decoradores de Python. El decorador @property accederá a funCalls y catPicture_served. Ahora crearemos un objeto de la clase Puntero.
pt = Pointer() pt.funCalls() pt.catPicture_served
Aquí necesitamos incrementar estos valores.
class Pointer(object): # ... def increament(self): self._metrices['funCalls'] += 1 def cat_pics(self): self._metrices['catPictures_served'] += 1
Hemos definido dos nuevos métodos: increment() y cat_pics(). Hemos modificado los valores usando estas funciones en el dictado de matrices. Aquí, podemos cambiar la clase de la misma manera que modificamos el puntero.
pt = Pointer() pt.increment() pt.increment() pt.funCalls()
Módulo de tipos de Python
El módulo Python ctypes nos permite crear un puntero tipo C en Python. Este módulo es útil si queremos realizar una llamada de función a una biblioteca C que requiere un puntero. Entendamos el siguiente ejemplo.
Ejemplo: lenguaje C
void incr_one(int *x) { *x += 1; }
En la función anterior, hemos incrementado el valor de x en uno. Supongamos que guardamos el archivo anterior llamado incrPointer.c y escribimos el siguiente comando en la terminal.
$ gcc -c -Wall -Werror -fpic incrPointer.c $ gcc -shared -o libinc.so incrPointer.o
El primer comando compila incrPointer.c en un objeto llamado incrPointer.o. El segundo comando acepta el archivo objeto y produce libinic.so para colaborar con ctypes.
ordenamiento por selección en java
import ctypes ## libinc.so library should be same directory as this program lib = ctypes.CDLL('./libinc.so') lib.increment
Producción:
En el código anterior, el ctypes.CDLL devuelve un objeto compartido llamado libinic.so. Contiene el incrPuntero() función. Si necesitamos especificar el puntero a las funciones que definimos en un objeto compartido, debemos especificarlo usando ctypes. Veamos el siguiente ejemplo.
inc = lib.increment ## defining the argtypes inc.argtypes = [ctypes.POINTER(ctypes.c_int)]
Si llamamos a la función usando un tipo diferente, se producirá un error.
incrPointer(10)
Producción:
Traceback (most recent call last): File '', line 1, in ctypes.ArgumentError: argument 1: : expected LP_c_int instance instead of int
Esto se debe a que incrPointer requiere un puntero y ctypes es una forma de pasar puntero en Python.
v = ctypes.c_int(10)
v es una variable C. Los ctypes proporcionan el método llamado porref() que solía pasar la referencia de la variable.
inc(ctypes.byref(a)) a
Producción:
c_int(11)
Hemos aumentado el valor utilizando la variable de referencia.
Conclusión
Hemos comentado que el puntero no está presente en Python, pero podemos implementar el mismo comportamiento con el objeto *mutable. También analizamos los módulos ctypes que pueden definir el puntero C en Python. Hemos definido algunas formas excelentes de simular un puntero en Python.