❶ python怎麼向類中的函數傳遞參數
Python中函數參數的傳遞是通過「賦值」來傳遞的。但這條規則只回答了函數參數傳遞的「戰略問題」,並沒有回答「戰術問題」,也就說沒有回答怎麼賦值的問題。函數參數的使用可以分為兩個方面,一是函數參數如何定義,二是函數在調用時的參數如何解析的。而後者又是由前者決定的。函數參數的定義有四種形式:
1. F(arg1,arg2,...)
2. F(arg2=<value>,arg3=<value>...)
3. F(*arg1)
4. F(**arg1)
第1 種方式是最「傳統」的方式:一個函數可以定義不限個數參數,參數(形式參數)放在跟在函數名後面的小括弧中,各個參數之間以逗號隔開。用這種方式定義的函數在調用的時候也必須在函數名後的小括弧中提供相等個數的值(實際參數),不能多也不能少,而且順序還必須相同。也就是說形參和實參的個數必須一致,而且想給形參1的值必須是實參中的第一位,形參與實參之間是一一對應的關系,即「形參1=實參1 形參2=實參2...」。很明顯這是一種非常不靈活的形式。比如:"def addOn(x,y): return x + y",這里定義的函數addOn,可以用addOn(1,2)的形式調用,意味著形參x將取值1,主將取值2。addOn(1,2,3)和addOn (1)都是錯誤的形式。
第2種方式比第1種方式,在定義的時候已經給各個形參定義了默認值。因此,在調用這種函數時,如果沒有給對應的形式參數傳遞實參,那麼這個形參就將使用默認值。比如:「def addOn(x=3,y=5): return x + y」,那麼addOn(6,5)的調用形式表示形參x取值6,y取值5。此外,addOn(7)這個形式也是可以的,表示形參x取值7,y取默認值5。這時候會出現一個問題,如果想讓x取默認值,用實參給y賦值怎麼辦?前面兩種調用形式明顯就不行了,這時就要用到Python中函數調用方法的另一大絕招 ──關健字賦值法。可以用addOn(y=6),這時表示x取默認值3,而y取值6。這種方式通過指定形式參數可以實現可以對形式參數進行「精確攻擊」,一個副帶的功能是可以不必遵守形式參數的前後順序,比如:addOn(y=4,x=6),這也是可以的。這種通過形式參數進行定點賦值的方式對於用第1種方式定義的函數也是適用的。
上面兩種方式定義的形式參數的個數都是固定的,比如定義函數的時候如果定義了5個形參,那麼在調用的時候最多也只能給它傳遞5個實參。但是在實際編程中並不能總是確定一個函數會有多少個參數。第3種方式就是用來應對這種情況的。它以一個*加上形參名的方式表示,這個函數實際參數是不一定的,可以是零個,也可以是N個。不管是多少個,在函數內部都被存放在以形參名為標識符的tuple中。比如:
對這個函數的調用addOn() addOn(2) addOn(3,4,5,6)等等都是可以的。
與第3種方式類似,形參名前面加了兩個*表示,參數在函數內部將被存放在以形式名為標識符的dictionary中。這時候調用函數必須採用key1=value1、key2=value2...的形式。比如:
1. def addOn(**arg):
2. sum = 0
3. if len(arg) == 0: return 0
4. else:
5. for x in arg.itervalues():
6. sum += x
7. return sum
那麼對這個函數的調用可以用addOn()或諸如addOn(x=4,y=5,k=6)等的方式調用。
上面說了四種函數形式定義的方式以及他們的調用方式,是分開說的,其實這四種方式可以組合在一起形成復雜多樣的形參定義形式。在定義或調用這種函數時,要遵循以下規則:
1. arg=<value>必須在arg後
2. *arg必須在arg=<value>後
3. **arg必須在*arg後
在函數調用過程中,形參賦值的過程是這樣的:
首先按順序把「arg」這種形式的實參給對應的形參
第二,把「arg=<value>」這種形式的實參賦值給形式
第三,把多出來的「arg」這種形式的實參組成一個tuple給帶一個星號的形參
第四,把多出來的「key=value」這種形式的實參轉為一個dictionary給帶兩個星號的形參。
例子:
1. def test(x,y=5,*a,**b):
2. print x,y,a,b
就這么一個簡單函數,來看看下面對這個函數調用會產生什麼結果:
test(1) ===> 1 5 () {}
test(1,2) ===> 1 2 () {}
test(1,2,3) ===> 1 2 (3,) {}
test(1,2,3,4) ===> 1 2 (3,4)
test(x=1) ===> 1 5 () {}
test(x=1,y=1) ===> 1 1 () {}
test(x=1,y=1,a=1) ===> 1 1 () {'a':1}
test(x=1,y=1,a=1,b=1) ===> 1 1 () {'a':1,'b':1}
test(1,y=1) ===> 1 1 () {}
test(1,2,y=1) ===> 出錯,說y給賦了多個值
test(1,2,3,4,a=1) ===> 1 2 (3,4) {'a':1}
test(1,2,3,4,k=1,t=2,o=3) ===> 1 2 (3,4) {'k':1,'t':2,'o':3}
❷ python函數的參數傳遞是傳值還是傳引用
那要看數據類型了,int,float,str這種就是傳值,list,dict,類的實例,自定義對象都是穿引用。
下面是示例代碼:
defchange(int1,float1,str1,dict1,obj1,list1):
int1+=1
float1+=1
str1+='changed'
dict1['none_exist_key']='none_exist_value'
obj1=None
list1.append('change')
classobj:
pass
int1=0
float1=0.0
str1='origin'
dict1={'key':'value'}
obj1=obj()
list1=['only_element']
print(int1)
print(float1)
print(str1)
print(dict1)
print(obj1)
print(list1)
change(int1,float1,str1,dict1,obj1,list1)
print('afterchange')
print(int1)
print(float1)
print(str1)
print(dict1)
print(obj1)
print(list1)
不明白可追問
❸ python參數傳遞是值傳遞還是引用傳遞
首先還是應該科普下函數參數傳遞機制,傳值和傳引用是什麼意思?
函數參數傳遞機制問題在本質上是調用函數(過程)和被調用函數(過程)在調用發生時進行通信的方法問題。基本的參數傳遞機制有兩種:值傳遞和引用傳遞。
值傳遞(passl-by-value)過程中,被調函數的形式參數作為被調函數的局部變數處理,即在堆棧中開辟了內存空間以存放由主調函數放進來的實參的值,從而成為了實參的一個副本。值傳遞的特點是被調函數對形式參數的任何操作都是作為局部變數進行,不會影響主調函數的實參變數的值。
引用傳遞(pass-by-reference)過程中,被調函數的形式參數雖然也作為局部變數在堆棧中開辟了內存空間,但是這時存放的是由主調函數放進來的實參變數的地址。被調函數對形參的任何操作都被處理成間接定址,即通過堆棧中存放的地址訪問主調函數中的實參變數。正因為如此,被調函數對形參做的任何操作都影響了主調函數中的實參變數。
在python中實際又是怎麼樣的呢?
先看一個簡單的例子:
結論:python不允許程序員選擇採用傳值還是傳引用。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 傳參數cmd怎麼往python中傳參數
如果你用C給Matlab寫過MEX程序,那麼這個問題是很容易理解的(好像每次討論Python問題時我總是把Matlab搬了出來…… 《在Matlab中把struct當成Python中的Dictionary使用》《Matlab和Python的幾種數據類型的比較》)。
既然提到了MEX,就簡單說一下:
一個Matlab可能形如
function ret=add3(a,b,c)
如果在C的層面實現這個函數,就會看到另一種景象:
void mexFunction(int nlhs,mxArray * plhs[],int nrhs,const mxArray * prhs[])
a,b,c三個參數的地址放在一個指針數組里,然後把這個指針數組的首地址作為參數prhs傳遞給函數,這說明Matlab函數的參數是傳遞指針的,而不是值傳遞。
縱然是傳遞的指針,但是卻不能在函數里改變實參的值,因為標記為逗const地了。
Python是開放源碼的,我沒有看。所以下面很多東西是猜的。
Python在函數的參數傳遞時用的什麼手法看實驗一下(使用ActivePython2.5):
首先介紹一個重要的函數:
>>> help(id)
Help on built-in function id in mole __builtin__:
id(...)
id(object) -> integer
Return the identity of an object. This is guaranteed to be unique among
simultaneously existing objects. (Hint: it's the object's memory address.)
看最後括弧里那句:Hint:it's the object's address.(它是對象的地址)
有了這個函數,下面的事情就方便多了。
>>> a=0
>>> id(a)
3630228
>>> a=1
>>> id(a)
3630216
可以看出,給a賦一次值,a的address就改變了。在C的層面看,(也許真實情況不是下面的樣子,但作為一個類比應該還是可以的):
void * pa;
pa=malloc(sizeof(int));
*(int *)pa=0;
free(pa);
pa=malloc(sizeof(int));
*(int *)pa=1;
Python中每次賦值會改變變數的address,分配新的內存空間,所以Python中對於類型不像C那樣嚴格要求。
下面看看Python函數參數傳遞時到底傳的什麼:
有一個函數:
>>> def changeA(a):
... print id(a)
... a=100
... print id(a)
設定一個變數var1:
>>> var1=10
>>> id(var1)
3630108
>>> changeA(var1)
3630108
3631012
>>> var1
10
調用函數後,從兩次print的結果可以看出,傳遞確實是地址。但是即便如此,在函數內對形參的修改不會對實參造成任何實質的影響,因為對形參的重新賦值,只是改變了形參所指向的內存單元(changeA里兩次調用print id(a)得到不同的結果),卻沒有改變實參的指向。在C的層面看也許類似下面的情節:
void changeA(void * pa)
{
pa=malloc(sizeof(int));
*(int *)pa=100;
free(pa);
}
精通C的你一眼就看出這個函數永遠也改變不了它外面的世界。
也就是說雖然傳遞的是地址,但像changeA這樣的函數改變不了實參的值。
也許會感到困擾看不,我已經在Matlab中習慣了。
一個最典型的例子就是Matlab中刪除結構體成員的rmfield函數(參見《Matlab筆記三則》),
(Matlab版本7.0.1)
如果想刪除結構體patient的name成員,用
rmfield(patient, 'name');
是永遠達不到目的的(就像試圖用雙手抓住自己的領子,把自己提到空中);
迷途知返的做法是:
patient = rmfield(patient, 'name');
❻ 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如何用列表向類傳參急!在線等!
無論是類的構造函數還是類的方法函數,都與普通函數一樣可以使用列表傳入多個實參。
class MyClass:
....def __init__(self:a,b,c):
........pass
對於MyClass,我們一般使用下列方式實例化:
x=MyClass(1,2,3)
如果我們實例化使用的參數在列表l中,可以這樣做:
l=[1,2,3]
x=MyClass(*l)
❽ python 如何向類方法傳入參數
classhello(object):
defworld(self,msg):
printmsg
c=hello()
c.world('helloworld')
❾ python將類作為參數傳遞
mport sys print sys.argv[1]#保存為main.py#在控制台下輸入 python main.py "hello"#就有hello列印出來了 前提是你配置好了環境變數