㈠ python 函數中,參數是傳值,還是傳引用
首先還是應該科普下函數參數傳遞機制,傳值和傳引用是什麼意思?
函數參數傳遞機制問題在本質上是調用函數(過程)和被調用函數(過程)在調用發生時進行通信的方法問題。基本的參數傳遞機制有兩種:值傳遞和引用傳遞。
值傳遞(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=2
print "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
2
39601564
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
發現一樣的傳值,而第二個變數居然變化,為啥呢?
實際上是因為python中的序列:列表是一個可變的對象,就基於list1=[1,2] list1[0]=[0]這樣前後的查看list1的內存地址,是一樣的。
>>> list1=[1,2]
>>> id(list1)
64185208
>>> list1[0]=[0]
>>> list1
[[0], 2]
>>> id(list1)
64185208
結論:python不允許程序員選擇採用傳值還是傳引用。Python參數傳遞採用的肯定是「傳對象引用」的方式。這種方式相當於傳值和傳引用的一種綜合。如果函數收到的是一個可變對象(比如字典或者列表)的引用,就能修改對象的原始值--相當於通過「傳引用」來傳遞對象。如果函數收到的是一個不可變對象(比如數字、字元或者元組)的引用,就不能直接修改原始對象--相當於通過「傳值'來傳遞對象。
分類: python 基礎語法
㈡ python 如何向類方法傳入參數
classhello(object):
defworld(self,msg):
printmsg
c=hello()
c.world('helloworld')
㈢ python,wxpython的不同類間的數據傳遞問題
你問的是幾個問題。ADD是wx frame的內部處理函數,不能從外部直接調用。具體原因,你可以查一下GUI的原理。GUI是一個事件驅動的封閉體系,是一個服務。你直接調用就破壞了人家的消息處理機制。所以是不允許的。
第二個問題就變數傳遞,在python里有多種辦法,最簡單的就是用global 修飾一個變數,這樣就可以在不同的線程,不同的模塊間直接使用。具體使用辦法,你看一下幫助。 需要在使用前用global 指定要全局化的變數
第三個問題。點擊按鈕觸發事件。這樣的事情,直接在按鈕事件處理函數里處理就可以了。不用調用外部函數。沒有理由,也沒有必要。
如果你希望讓系統容易閱讀一些,就把GUI的構建代碼,事件處理代碼,數據描述代碼,業務邏輯代碼分別寫在不同的模塊里。這就是典型的MVC模型。
還有一個簡單的辦法。shownum這個函數的入口,加一個參數,將frame傳遞進去。這樣shownum就可以直接訪問frame類的所有內置公開變數。列印更不在話下。
最後附帶說明一下, 你的函數命名,變數命名一定要有意思。不要再用「按鈕1」, 「按鈕2」, output這樣的命名。 你的shownum命名就不錯。
㈣ python如何將值傳遞參數
python將值傳遞參數的方法:
將值賦給變數url,然後調用函數,將url寫到函數名後面的括弧中,這樣就可以將值傳遞給函數的參數y了
示例代碼如下:
執行結果如下:
更多Python知識,請關註:Python自學網!!
㈤ python將類作為參數傳遞
mport sys print sys.argv[1]#保存為main.py#在控制台下輸入 python main.py "hello"#就有hello列印出來了 前提是你配置好了環境變數
㈥ Python 的函數是怎麼傳遞參數的
對象vs變數
在python中,類型屬於對象,變數是沒有類型的,這正是python的語言特性,也是吸引著很多pythoner的一點。所有的變數都可以理解是內存中一個對象的「引用」,或者,也可以看似c中void*的感覺。所以,希望大家在看到一個python變數的時候,把變數和真正的內存對象分開。
類型是屬於對象的,而不是變數。
這樣,很多問題就容易思考了。
例如:
對象vs變數
12
nfoo = 1 #一個指向int數據類型的nfoo(再次提醒,nfoo沒有類型)lstFoo = [1] #一個指向list類型的lstFoo,這個list中包含一個整數1
可更改(mutable)與不可更改(immutable)對象
對應於上一個概念,就必須引出另了另一概念,這就是可更改(mutable)對象與不可更改(immutable)對象。
對於python比較熟悉的人們都應該了解這個事實,在python中,strings, tuples, 和numbers是不可更改的對象,而list,dict等則是可以修改的對象。那麼,這些所謂的可改變和不可改變影響著什麼呢?
可更改vs不可更改
12345
nfoo = 1nfoo = 2lstFoo = [1]lstFoo[0] = 2
代碼第2行中,內存中原始的1對象因為不能改變,於是被「拋棄」,另nfoo指向一個新的int對象,其值為2
代碼第5行中,更改list中第一個元素的值,因為list是可改變的,所以,第一個元素變更為2。其實應該說,lstFoo指向一個包含一個對象的數組。賦值所發生的事情,是有一個新int對象被指定給lstFoo所指向的數組對象的第一個元素,但是對於lstFoo本身來說,所指向的數組對象並沒有變化,只是數組對象的內容發生變化了。這個看似void*的變數所指向的對象仍舊是剛剛的那個有一個int對象的list。
如下圖所示:
Python的函數參數傳遞:傳值?引用?
對於變數(與對象相對的概念),其實,python函數參數傳遞可以理解為就是變數傳值操作,用C++的方式理解,就是對void*賦值。如果這個變數的值不變,我們看似就是引用,如果這個變數的值改變,我們看著像是在賦值。有點暈是吧,我們仍舊據個例子。
不可變對象參數調用
12345
def ChangeInt( a ): a = 10nfoo = 2 ChangeInt(nfoo)print nfoo #結果是2
這時發生了什麼,有一個int對象2,和指向它的變數nfoo,當傳遞給ChangeInt的時候,按照傳值的方式,復制了變數nfoo的值,這樣,a就是nfoo指向同一個Int對象了,函數中a=10的時候,發生什麼?(還記得我上面講到的那些概念么),int是不能更改的對象,於是,做了一個新的int對象,另a指向它(但是此時,被變數nfoo指向的對象,沒有發生變化),於是在外面的感覺就是函數沒有改變nfoo的值,看起來像C++中的傳值方式。
可變對象參數調用
12345
def ChangeList( a ): a[0] = 10lstFoo = [2]ChangeList(lstFoo )print nfoo #結果是[10]
當傳遞給ChangeList的時候,變數仍舊按照「傳值」的方式,復制了變數lstFoo 的值,於是a和lstFoo 指向同一個對象,但是,list是可以改變的對象,對a[0]的操作,就是對lstFoo指向的對象的內容的操作,於是,這時的a[0] = 10,就是更改了lstFoo 指向的對象的第一個元素,所以,再次輸出lstFoo 時,顯示[10],內容被改變了,看起來,像C++中的按引用傳遞。
㈦ python 像這樣定義多線程的類在調用時怎麼把調用父類的參數傳遞給子函數
你已經實現了啊。在__init__初始化參數里,將參數傳遞進去。
另外因為線程工作在主程序同一個空間里,所以可以用全局變數傳遞。比如定義一個global v,然後在主程序里設置好。
再在線程里用global v來引用。
如果在線程運行當中,動態的改參數。可以象是這里的thread_stop設置。由主進程與從進程單對單的傳遞信號。
另外還可以通過隊列。這個好處是有一個鎖,可以全局使用。
此外你還可以引入一個消息管理器。各個線程與主進程直接通過消息傳遞變數。
進程之間也可以通過共享內存來實現RPC通信,就是交換數據。
線程處理完的數據,如果主程序想處理。可以這樣。讓線程通過全局變數,通過隊列傳回來。
不過主進程通常還有一個任務,就是監督線程的完成退處,並管理線程中止信號。
比如你這個程序少了一個
thread.join() 這里的join可以加一個timeout,當超時時,主進程就可以脫身出來,做一些其它的事情,比如處理返回數值。 如果線程通過一個數組變數將狀態傳回主進程。這樣輪洵子線程狀態會比join的效率更高。
你這個程序里用文件傳遞也不是不可以。這是一個很好思路。當你傳遞變數困難時,可以用文件。或者是資料庫。
㈧ Python 值傳遞,引用傳遞
常見的參數傳遞有 2 種:值傳遞和引用傳遞。所謂值傳遞,通常就是拷貝參數的值,然後傳遞給函數里的新變數。這樣,原變數和新變數之間互相獨立,互不影響。
所謂引用傳遞,通常是指把參數的引用傳給新的變數,這樣,原變數和新變數就會指向同一塊內存地址。如果改變了其中任何一個變數的值,那麼另外一個變數也會相應地隨之改變。
在 Python 中:
變數的賦值,只是表示讓變數指向了某個對象,並不表示拷貝對象給變數;而一個對象,可以被多個變數所指向。
可變對象(列表,字典,集合等等)的改變,會影響所有指向該對象的變數。
對於不可變對象(字元串、整型、元組等等),所有指向該對象的變數的值總是一樣的,也不會改變。但是通過某些操作(+= 等等)更新不可變對象的值時,會返回一個新的對象。
變數可以被刪除,但是對象無法被刪除。
㈨ python在定義類的時候,如何把類函數傳遞給另一個變數,如下
函數是組織好的,可重復使用的,用來實現單一,或相關聯功能的代碼段。
函數能提高應用的模塊性,和代碼的重復利用率。你已經知道Python提供了許多內建函數,比如print()。但你也可以自己創見函數,這被叫做用戶自定義函數。
一、定義一個函數
你可以定義一個由自己想要功能的函數,以下是簡單的規則:
1.函數代碼塊以def關鍵詞開頭,後接函數標識符名稱和圓括弧()。
2.任何傳入參數和自變數必須放在圓括弧中間。圓括弧之間可以用於定義參數。
3.函數的第一行語句可以選擇性地使用文檔字元串—用於存放函數說明。
4.函數內容以冒號起始,並且縮進。
5.Return[expression]結束函數,選擇性地返回一個值給調用方。不帶表達式的return相當於返回 None。
語法
復制代碼代碼如下:
def functionname( parameters ):
"函數_文檔字元串"
function_suite
return [expression]
默認情況下,參數值和參數名稱是按函數聲明中定義的的順序匹配起來的。
實例
以下為一個簡單的Python函數,它將一個字元串作為傳入參數,再列印到標准顯示設備上。
復制代碼代碼如下:
def printme( str ):
"列印傳入的字元串到標准顯示設備上"
print str
return
二、函數調用
定義一個函數只給了函數一個名稱,指定了函數里包含的參數,和代碼塊結構。這個函數的基本結構完成以後,你可以通過另一個函數調用執行,也可以直接從Python提示符執行。
如下實例調用了printme()函數:
復制代碼代碼如下:
#!/usr/bin/python
# Function definition is here
def printme( str ):
"列印任何傳入的字元串"
print str;
return;
# Now you can call printme function
printme("我要調用用戶自定義函數!");
printme("再次調用同一函數");
#以上實例輸出結果:
#我要調用用戶自定義函數!
#再次調用同一函數
㈩ python 給函數傳遞一個自定義的類的實例,是傳值還是傳址
python不允許程序員選擇採用傳值還是傳引用。Python參數傳遞採用的肯定是「傳對象引用」的方式。這種方式相當於傳值和傳引用的一種綜合。如果函數收到的是一個可變對象(比如字典或者列表)的引用,就能修改對象的原始值--相當於通過「傳引用」來傳遞對象。如果函數收到的是一個不可變對象(比如數字、字元或者元組)的引用,就不能直接修改原始對象--相當於通過「傳值'來傳遞對象。
原文來自:https://www.cnblogs.com/loleina/p/5276918.html