首先還是應該科普下函式引數傳遞機制,傳值和傳引用是什麼意思?
函式引數傳遞機制問題在本質上是呼叫函式(過程)和被呼叫函式(過程)在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種:值傳遞和引用傳遞。
值傳遞(passl-by-value)過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在堆疊中開闢了記憶體空間以存放由主調函式放進來的實參的值,從而成為了實參的乙個副本。值傳遞的特點是被調函式對形式引數的任何操作都是作為區域性變數進行,不會影響主調函式的實參變數的值。()(實體地址改變)
函式式程式設計:決定流程封裝函式通過主函式呼叫
引用傳遞(pass-by-reference)過程中,被調函式的形式引數雖然也作為區域性變數在堆疊中開闢了記憶體空間,但是這時存放的是由主調函式放進來的實參變數的位址。被調函式對形參的任何操作都被處理成間接定址,即通過堆疊中存放的位址訪問主調函式中的實參變數。正因為如此,被調函式對形參做的任何操作都影響了主調函式中的實參變數。(實體地址不變,如對列表操作)
類程式設計 分析過程 功能模組劃分 每個模組步驟拆分 然後進行屬性封裝在python中實際又是怎麼樣的呢?
先看乙個簡單的例子:
from ctypes import *
import os.path
import sys
def test(c):
print "test before "
print id(c)
c+=2
print "test after +"
print id(c)
return c
def printit(t):
for i in range(len(t)):
print t[i]
if __name__=="__main__":
a=2print "main before invoke test"
print id(a)
n=test(a)
print "main afterf invoke test"
print a
print id(a)
執行後結果如下:
>>>
main before invoke test
39601564
test before
39601564
test after +
39601540
main afterf invoke test
239601564
id函式可以獲得物件的記憶體位址.很明顯從上面例子可以看出,將a變數作為引數傳遞給了test函式,傳遞了a的乙個引用,把a的位址傳遞過去了,所以在函式內獲取的變數c的位址跟變數a的位址是一樣的,但是在函式內,對c進行賦值運算,c的值從2變成了4,實際上2和4所佔的記憶體空間都還是存在的,賦值運算後,c指向4所在的記憶體。而a仍然指向2所在的記憶體,所以後面列印a,其值還是2.
如果還不能理解,先看下面例子
>>> a=1
>>> b=1
>>> id(a)
40650152
>>> id(b)
40650152
>>> a=2
>>> id(a)
40650140
a和b都是int型別的值,值都是1,而且記憶體位址都是一樣的,這已經表明了在python中,可以有多個引用指向同乙個記憶體(畫了乙個很挫的圖,見諒),在給a賦值為2後,再次檢視a的記憶體位址,都已經變化了
而基於最前面的例子,大概可以這樣描述:
那python函式傳參就是傳引用?然後傳參的值在被調函式內被修改也不影響主調函式的實參變數的值?再來看個例子。
from ctypes import *
import os.path
import sys
def test(list2):
print "test before "
print id(list2)
list2[1]=30
print "test after +"
print id(list2)
return list2
def printit(t):
for i in range(len(t)):
print t[i]
if __name__=="__main__":
list1=["loleina",25,'female']
print "main before invoke test"
print id(list1)
list3=test(list1)
print "main afterf invoke test"
print list1
print id(list1)
實際值為:
>>>
main before invoke test
64129944
test before
64129944
test after +
64129944
main afterf invoke test
['loleina', 30, 'female']
64129944
發現一樣的傳值,而第二個變數居然變化,為啥呢?
>>> list1=[1,2]
>>> id(list1)
64185208
>>> list1[0]=[0]
>>> list1
[[0], 2]
>>> id(list1)
64185208
結論:python不允許程式設計師選擇採用傳值還是傳引用。python引數傳遞採用的肯定是「傳物件引用」的方式。這種方式相當於傳值和傳引用的一種綜合。如果函式收到的是乙個可變物件(比如字典或者列表)的引用,就能修改物件的原始值--相當於通過「傳引用」來傳遞物件。如果函式收到的是乙個不可變物件(比如數字、字元或者元組)的引用,就不能直接修改原始物件--相當於通過「傳值'來傳遞物件。 函式傳引數 python傳參是傳值還是傳引用
在此之前先來看看變數和物件的關係 python 中一切皆為物件,數字是物件,列表是物件,函式也是物件,任何東西都是物件。而變數是物件的乙個引用 又稱為名字或者標籤 物件的操作都是通過引用來完成的。例如,a 是乙個空列表物件,變數 a 是該物件的乙個引用 例1 輸出例2 輸出 id不一樣,所以說不是同...
函式傳值傳參
var obj function x 內部宣告的變數不會影響外面的obj物件 console.log obj.n 2 obj 傳入的是乙個指標 值 x是obj指標的副本,兩者都指向同乙個物件 console.log obj.n 3 例子二 var x 1 function a x a x conso...
Python函式傳參
首先還是應該科普下函式引數傳遞機制,傳值和傳引用是什麼意思?函式引數傳遞機制問題在本質上是呼叫函式 過程 和被呼叫函式 過程 在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種 值傳遞和引用傳遞。值傳遞 passl by value 過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在...