python中的列表是指针吗_Python中的指针——到底指什么(二)
在 Python中的指針——到底指什么(一) 中,我們知道在Python的一切都是對象,變量其實是指向PyObject對象的名稱,對不可變變量進行操作后,名稱指向了另一個PyObject。
扣留對象
>>> x=256
>>> y=256
>>> x is y
True
>>> x=257
>>> y=257
>>> x is y
False
x、y都是256的時候,它們指向了同一個PyObject,x、y都是257時,它們指向了不同的對象,背后的原因是什么?Python會預先在內存中創建扣留對象(Interned Object)供用戶使用。扣留對象的創建和Python的實現有關,一般來說包括小整數([-5,256])、字符串常量([a-zA-Z0-9_],即大小寫英文字母、數字和下劃線,且字符串長度不大于20)。扣留對象相當于緩沖池,是為了減少內存占用而引入的機制。上述例子中,值為256的整形對象屬于扣留對象,所以每次對其引用時都不需要創建新的對象,而是直接將引用計數加1即可,值為257的對象不屬于扣留對象,所以每次要創建新對象。
注1:在Shell中結果如此,如果是通過.py文件運行,由于Python的窺孔優化(peephool optimization),一個作用域的代碼會被編譯為一個Code對象,同一個Code對象中重復出現的變量名和常量只會保存一次。
注2:如果想得到一個非默認扣留對象的扣留對象,可以使用sys.intern()函數。其應用場景之一就是提高字典查找的性能——如果字典中的key是扣留對象,要查找的key也是扣留對象,就會直接通過對象地址比較查找對象,而不需要進行字符串的比較。
模擬指針
雖然Python中沒有原生的指針,但可以通過以下方式模擬指針:
使用內置的可變變量,如list、set、dictionary等;
使用自定義對象,其內部實現還是通過內置的可變變量。
使用C定義函數:
void add_some( int * x, int some )
{
*x += some;
}
通過整形指針參數x,實現將x的數值增加some參數指定的值。在Python中要模擬這種實現,可以將可變列表作為函數的參數:
>>> def add_some(x, some):
x[0] += some
>>> y = [12]
>>> add_some(y, 6)
>>> y
[18]
>>> z = (12,)
>>> add_some(z, 6)
Traceback (most recent call last):
File "", line 1, in
add_some(z, 6)
File "", line 2, in add_some
x[0] += some
TypeError: 'tuple' object does not support item assignment
函數add_some將列表的第一個元素增加some實現了類似指針的功能。但并不能說明Python中是有指針的,僅能說明list是可變類型,如果將元組作為參數調用add_some函數,就會拋出類型錯誤的異常,說明元組是不可變類型。
除了list外,經常使用dict在自定義類模擬指針:
>>> class Metric:
def __init__(self):
self._metric = {'func_called':0}
@property
def func_called(self):
return self._metric['func_called']
def test_func(self):
self._metric['func_called'] += 1
>>> metr = Metric()
>>> metr.func_called
0
>>> metr.test_func()
>>> metr.func_called
1
使用ctypes提供的pointer函數可以獲取對象的真正指針,POINTER函數可以定義指針類型,具體可以參考ctypes的官文。
總結
以上是生活随笔為你收集整理的python中的列表是指针吗_Python中的指针——到底指什么(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python关于七巧板的代码_Css打造
- 下一篇: 引导u盘怎么制作工具 制作U盘引导工具方