Python 中的指针

Manav Narula 2023年10月10日
  1. 在 Python 中使用 id() 函数返回对象的内存地址
  2. 在 Python 中使用 ctypes.pointer() 函数创建指针变量
Python 中的指针

C 和 C++ 有一个有趣的特性就是指针。指针是可以存储对象内存地址的变量。

* 运算符用于创建指针。相同的运算符可用于访问给定地址的值。

但是,在 Python 中,没有这样的功能。本教程将讨论为什么 Python 中不存在此功能,以及我们如何在某种程度上模拟它们。

尽管是一个非常有用的工具,但对于初学者级别的程序员来说,指针可能有点难以掌握。它还可能导致与内存管理相关的不同错误。

它可能会导致各种问题,并可能导致我们访问不该访问的内容。

它违背了 Python 的 Zen 宗旨,即简单胜于复杂,显式胜于隐式。

Python 中的一切都是对象,可以是不可变的,也可以是可变的。可变对象可以随着代码的进展而改变,而我们不能改变不可变对象。

列表、集合、字典是 Python 中的可变对象。intfloatstrtuplesboolean 等对象是不可变的。

每当我们对不可变对象进行任何更改时,我们都会创建新对象。我们可以在下面的代码中验证这一点。

在 Python 中使用 id() 函数返回对象的内存地址

a = 5
print(id(a))
a = a + 2
print(id(a))

输出:

140731589698064
140731589698128

在上面的例子中,id() 函数返回一个对象的内存地址。你可以观察变量 a 之前和之后的内存地址。

这就是为什么在 Python 中使用指针是不可行的。另一个原因是 C/C++ 和 Python 中变量之间的内存分配不同。

在 C/C++ 中,当我们创建变量时,会为变量分配一些内存,并将值分配给该位置。

变量名指向这个分配的内存。然而,在 Python 中,它并不是那么简单。

在 Python 中,会创建一个新的 PyObject,然后分配给定对象的 typecode。提供了这个对象的值,变量名指向这个对象。

该对象的 refcount 增加 1。对不可变对象类型进行更改时,将创建一个新对象,并且前一个对象的 refcount 减少 1

使用可变对象,可以复制一些简单的指针功能。

例如,如果我们采用前面的示例,则通过增加一个整数来创建一个新对象。如果我们希望避免这种情况,我们可以使用列表。

列表是可变的。所以我们可以将值存储在一个列表中并更新它。

a = [5]
print(id(a))
a[0] = a[0] + 5
print(id(a))

输出:

2063886567688
2063886567688

在上面的示例中,我们将一些值存储在 list 中。然后,我们通过将其增加 5 来修改此值。

但是,我们可以观察到更新值后内存位置是相同的。

在 Python 中使用 ctypes.pointer() 函数创建指针变量

我们可以在 Python 中模拟指针的另一种方法是使用 ctypes 模块。这是一个非常复杂的模块,但提供了加载 C 库并将 Python 包裹起来的功能。

import ctypes

a = ctypes.pointer(ctypes.c_int(5))
print(a)

输出:

<ctypes.wintypes.LP_c_long object at 0x000001E0894E66C8>

在上面的示例中,你可以观察到我们使用 ctype 模块创建了一个整数指针变量。

必须使用此模块加载下载的库才能使用不同的功能。

作者: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn