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