PHP和Python中的引用機制

2021-07-31 10:14:55 字數 3241 閱讀 7166

php 和 

python 語言

中引用是非常重要的乙個概念,這個概念對於理解兩門語言非常重要,會讓你更深刻的認識到兩門語言的本質,所以簡單的談一談。先說結論,python 語言中一切都是物件,理解起來覺得更合理;php 則是混搭機制,對於引用的處理讓人很困惑。

python 中的引用

在 python 中一切都是物件,整型值、字典、元祖都是物件,連函式、類本身也是物件,定義乙個函式,即使程式沒有呼叫,可在執行的時候,其本身也是乙個物件。

物件分三部分,身份,型別和值,身份就是乙個變數識別符號,由 python 解析器維護,可以通過 id() 函式獲取變數編號。而值是具體儲存的內容(在記憶體中有乙個位址),通過變數名將具體的物件關聯起來(可以說是引用)。當 python 發現值(內容)沒有變數引用了,就會進行**。

結論在 python 中,變數賦值和函式引數傳遞都是引用關係。

(1)看看乙個賦值或者函式引數傳遞發生了什麼:

m = "hello"n = m

上述語句 m 和 n 變數其實是引用的同一塊內容,m 和 n 不分主次,對它們進行查詢,就是對 "hello" 這個內容體進行查詢。

(2)當修改乙個變數值的時候發生了什麼?

這裡要區分下可變物件和不可變物件,可變物件表示變數名賦值就是直接在對應的內容體進行操作;而不可變物件表示變數對應的內容體是唯讀的(假如重新賦值實際是從新開闢一塊記憶體區)。

在 python 中整型和字串型別是不可變物件,其他是可變物件,看幾個例子:

m = "hello"n = m n = "good"

這段**中對 n 進行重新賦值操作的時候,不是在 "hello" 這個內容體上進行修改,而是重新建立了乙個內容體"good",n 變數則引用了它。

m =

n = m

print m

對於可變物件來說,上述**中,不管對 m 還是 n 進行更新,影響的是同一塊內容體。

下面看幾個例子,來更深刻的理解。

python 中的函式傳遞

理解了變數賦值,其實也理解了函式傳遞,原理是一致的,就是變數和物件的引用關係(繫結)。

(1)簡單的函式傳遞

def fun(m):

o =

fun(o)print o

o 這個實參和函式內的 m 形參引用的是同乙個內容體,這個普通的賦值其實是一樣的處理機制。

(2)複雜點的例子

class classobj(object):

v =

def fun(o) :

x =  o.v

return x

o = classobj()

s = fun(o)print s ,o.v

上面的**中,不管是對自定義類的例項屬性(o.v)進行操作,還是對函式返回的變數(s)進行操作,引用的都是同乙個內容儲存體。

(3)更複雜的例子

上面說了,函式定義過程中乙個形式引數,就算函式沒有被呼叫,在函式這個命名空間內,這個形式引數也是存在的(由 python 維護)。

def fun(s=):

return s

o1 = fun()

print o1

o2 = fun()

print o1,o2

可以看下結果,兩次函式呼叫,函式體內部指向的物件都是同乙個,不管函式呼叫多少次,其形參的 id 值是一樣的,其引用的內容體一直存在。

php 中的引用

php 剛出來的時候,為了簡單,任何的賦值、函式傳遞都是拷貝方式的,雖然可能很耗費空間並降低了處理速度,但是對於程式設計來說卻降低了難度。比如下面的**

$a = "china";

$b = $a ;

$b 和 $a 完全沒有關係,操作的是兩塊記憶體位址,相當與 $b 先讀取 $a 的內容,然後自己儲存乙份。

php 作為一門語言,一直在演化,也有了引用的概念,但是需要通過 & 符號來顯示的指明,屬於乙個語法糖。比如說下面的**:

$a = "china";$b = &$a ;$b = "world";

echo $a . "_" . $b ;$a = "good";echo $a . "_" . $b ;

通過 & 符號,則代表 $a 和 $b 指向的是同一塊內容。

引用的好處其實很簡單,第一是節省記憶體空間,比如在函式呼叫中,假如某個引數變數對應的值有 1k,假如不使用引用傳遞,則在函式執行的時候,就要額外拷貝 1k 的內容,這樣就節省了空間;第二就是提高處理速度,記憶體的拷貝必然會消耗 cpu 處理時間。

使用引用固然高效,但是也要留心,因為一不小心可能就破壞了原有變數的值,尤其在不理解引用的情況下,需要謹慎使用。

php 中的引用很困惑

手冊上說,php 可以通過三種方式使用引用

· 賦值

· 物件賦值或者函式傳遞物件

· 引用返回

說明下,目前的 php 版本,物件賦值或者函式傳遞物件,預設就是引用方式,不用加 & 符號,其實我建議加,因為這樣語言有一致性。

重點說下引用返回,上面 python 例子中,函式 return 返回乙個變數,當實際呼叫的時候,函式呼叫賦值給乙個變數,當這個變數的值改變後,函式體裡面的變數值也是同步修改的。比如:

class c(object):

o =

def __init__(self, arg):

super(c, self).__init__()

self.arg = arg

def r(self):

return self.o

obj = c(10)

objo = obj.r()print objo

比如函式呼叫返回的 objo 變數(應用 c 類中的變數)值修改後,c 這個類中的例項變數 o 也會同步修改。而在 php 中是做不到的,比如:

class c

}$obj = new c;

$objo = $obj->r();print $objo ;

$objo = "good" ;print $obj->r();

上面的** $objo 修改後,不會影響到例項的變數,可以通過引用返回解決這問題,但是語法讓人覺得難以理解。

class c

}$obj = new c;

$objo = &$obj->r();print $objo ;

$objo = "good" ;print $obj->r();

這裡面使用兩個 & 符號,函式中的 & 符號代表函式返回是個引用,第二個 & 符號表示不是賦值而是變數引用。

總體來說,python 中的引用和它的物件機制是一體的,而 php 中則是變相實現的引用。

php中的 引用

引用是什麼 在 php 中引用意味著用不同的名字訪問同乙個變數內容。這並不像 c 的指標,替代的是,引用是符號表別名。注意在 php 中,變數名和變數內容是不一樣的,因此同樣的內容可以有不同的名字。最接近的比喻是 unix 的檔名和檔案本身 變數名是目錄條目,而變數內容則是檔案本身。引用可以被看作是...

python中的引用和拷貝

引用是指儲存的值為物件的位址。在 python 語言中,乙個變數儲存的值除了基本型別儲存的是值外,其它都是引用,因此對於它們的使用就需要小心一些。下面舉個例子 引用 a false,false,false,false b ab 0 true print b print a true,false,fa...

python中引用的原理和python語言的型別

在python中,變數就是物件的引用。故變數中儲存的是其實是物件的位址,變數是通過物件的位址來最終完成物件的引用。python因為其簡潔性,所以在宣告變數的時候,並不需要自己來定義函式的資料型別,python的直譯器能自己確定變數的型別。python是動態型別語言 但也因為如此python的每個物件...