溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在Python中模擬實現(xiàn)指針

發(fā)布時間:2020-08-24 14:58:14 來源:億速云 閱讀:759 作者:Leah 欄目:編程語言

怎么在Python中模擬實現(xiàn)指針?針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

在Python中模擬實現(xiàn)指針

因為Python中的指針本身不存在,但并不意味著無法使用指針。實際上有多種方法可以在Python中模擬指針。

這里用兩種方法來實現(xiàn):

使用可變類型作為指針【Python中的變量】

使用自定義Python對象【Python中的對象】

使用可變類型作為指針

您已經(jīng)了解了可變類型。因為這些對象是可變的,所以您可以將它們視為指向模擬指針行為的指針。假設(shè)您要復(fù)制以下c代碼:

void  add_one (int  * x ) { 
    * x  + =  1 ; 
}

此代碼采用指向整數(shù)(*x)的指針,然后將該值遞增1。這是一個練習(xí)代碼的主要功能:

#include <stdio.h>
int main(void) {
    int y = 2337;
    printf("y = %d\n", y);
    add_one(&y);
    printf("y = %d\n", y);
    return 0;
}

在上面的代碼中,分配2337給y,打印出當(dāng)前值,將值遞增1,然后打印出修改后的值。執(zhí)行此代碼的輸出如下:

y = 2337 
y = 2338

在Python中復(fù)制此類行為的一種方法是使用可變類型??紤]使用列表并修改第一個元素:

>>> def  add_one (x ):
...     x [ 0 ]  + =  1 
... 
>>> y  =  [ 2337 ] 
>>> add_one (y )
>>> y [ 0 ] 
2338

在這里,add_one(x)訪問第一個元素并將其值增加1。使用一種list方法,最終結(jié)果似乎已修改了該值。那么Python中的指針確實存在嗎?好吧,這是唯一可能的,因為它list是一種可變類型。如果您嘗試使用a tuple,則會收到錯誤消息:

>>> z = (2337,)
>>> add_one(z)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in add_one
TypeError: 'tuple' object does not support item assignment

上面的代碼演示了這tuple是不可變的。因此,它不支持項目分配。list不是唯一可變的類型。在Python中模仿指針的另一種常見方法是使用a dict。

假設(shè)您有一個應(yīng)用程序,您希望每次發(fā)生有趣事件時都要跟蹤它。實現(xiàn)此目的的一種方法是創(chuàng)建一個dict并使用其中一個項目作為計數(shù)器:

>>> counters = {"func_calls": 0}
>>> def bar():
...     counters["func_calls"] += 1
...
>>> def foo():
...     counters["func_calls"] += 1
...     bar()
...
>>> foo()
>>> counters["func_calls"]
2

在此示例中,counters字典用于跟蹤函數(shù)調(diào)用的數(shù)量。打電話后foo(),計數(shù)器已2按預(yù)期增加。所有因為dict是可變的。

請記住,這只是模擬指針行為,并不直接映射到C或C ++中的真指針。也就是說,這些操作比在C或C ++中更昂貴。

使用Python對象

該dict選項是在Python中模擬指針的好方法,但有時記住您使用的密鑰名稱會很繁瑣。如果您在應(yīng)用程序的各個部分使用字典,則尤其如此。這是自定義Python類可以真正幫助的地方。

要構(gòu)建最后一個示例,假設(shè)您要跟蹤應(yīng)用程序中的指標。創(chuàng)建一個類是抽象討厭細節(jié)的好方法:

class  Metrics (object ):
    def  __init __ (self ):
        self 。_metrics  =  { 
            “func_calls” : 0 ,
            “cat_pictures_served” : 0 ,
        }

此代碼定義了一個Metrics類。該類仍然使用a dict來保存實際數(shù)據(jù),該數(shù)據(jù)位于_metrics成員變量中。這將為您提供所需的可變性?,F(xiàn)在您只需要能夠訪問這些值。一個很好的方法是使用屬性:

class Metrics(object):
    # ...
    @property
    def func_calls(self):
        return self._metrics["func_calls"]
    @property
    def cat_pictures_served(self):
        return self._metrics["cat_pictures_served"]

這段代碼利用了@property。如果您不熟悉裝飾器,可以在Python裝飾器上查看這個Primer。@property這里的裝飾器允許您訪問func_calls,cat_pictures_served就像它們是屬性一樣:

>>> metrics = Metrics()
>>> metrics.func_calls
0
>>> metrics.cat_pictures_served
0

您可以將這些名稱作為屬性訪問這一事實意味著您抽象出這些值在a中的事實dict。您還可以更明確地了解屬性的名稱。當(dāng)然,您需要能夠增加這些值:

class Metrics(object):
    # ...
    def inc_func_calls(self):
        self._metrics["func_calls"] += 1
    def inc_cat_pics(self):
        self._metrics["cat_pictures_served"] += 1

這里再介紹兩種新方法:

inc_func_calls()
inc_cat_pics()

這些方法會修改指標中的值dict。您現(xiàn)在有一個類可以修改,就像您正在修改指針一樣:

>>> metrics = Metrics()
>>> metrics.inc_func_calls()
>>> metrics.inc_func_calls()
>>> metrics.func_calls
2

在這里,您可以在應(yīng)用程序中的各個位置訪問func_calls和調(diào)用inc_func_calls(),并在Python中模擬指針。當(dāng)您需要在應(yīng)用程序的各個部分中頻繁使用和更新指標時,這非常有用。

注意:特別是在這個類中,make inc_func_calls()和inc_cat_pics()explicit而不是使用@property.setter阻止用戶將這些值設(shè)置為任意int或無效的值,如dict。

class Metrics(object):
    def __init__(self):
        self._metrics = {
            "func_calls": 0,
            "cat_pictures_served": 0,
        }
    @property
    def func_calls(self):
        return self._metrics["func_calls"]
    @property
    def cat_pictures_served(self):
        return self._metrics["cat_pictures_served"]
    def inc_func_calls(self):
        self._metrics["func_calls"] += 1
    def inc_cat_pics(self):
        self._metrics["cat_pictures_served"] += 1

關(guān)于怎么在Python中模擬實現(xiàn)指針問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI