函數可變參傳值(python)


1、定義方法的基本語法
def fun(n,m,...)
 ....
 ....
 ....
 (return n)

關於return:
1,return可以有,可以沒有,
2,沒有return的方法返回None,
3,return后面沒有表達式也是返回None,
4,函數無法到達結尾也返回None。

例:

def test(a,b):

c=a+b

上函數沒有return,故輸入test(1,2),沒有返回值。

def test(a,b):

c=a+b

return c

上函數加上了return,輸入test(1,2)

 

2、 Python中函數的參數定義和可變參數

Python中函數可以沒有參數,也可以由多個參數。

1.沒有參數的情況:

def funcA():
  pass
    
顯然,函數funcA沒有參數(同時啥也不干:D)。

 

2.兩個參數:

下面這個函數funcB就有兩個參數了,
def funcB(a, b):
  print a
  print b
調用的時候,我們需要使用函數名,加上圓括號擴起來的參數列表,比如funcB(100, 99),執行結果是:
100
99
很明顯,參數的順序和個數要和函數定義中一致,如果執行funcB(100),Python會報錯的:
TypeError: funcB() takes exactly 2 arguments (1 given)

 

3.形式參數:用函數的時候打亂參數傳遞的順序

上面的例子里,調用函數的時候,傳遞的參數都是根據位置來跟函數定義里的參數表匹配的,比如funcB(100, 99)和funcB(99, 100)的執行結果是不一樣的。在Python里,還支持一種用關鍵字參數(keyword argument)調用函數的辦法,也就是在調用函數的時候,明確指定參數值付給那個形參。比如還是上面的funcB(a, b),我們通過這兩種方式調用funcB(a=100, b=99)和funcB(b=99, a=100)
結果跟funcB(100, 99)都是一樣的,因為我們在使用關鍵字參數調用的時候,指定了把100賦值給a,99賦值給b。也就是說,關鍵字參數可以讓我們在調用函數的時候打亂參數傳遞的順序!

另外,在函數調用中,可以混合使用基於位置匹配的參數和關鍵字參數,前題是先給出固定位置的參數,比如
def funcE(a, b, c):
  print a
  print b
  print c
調用funcE(100, 99, 98)和調用funcE(100, c=98, b=99)的結果是一樣的。

 

4.設置參數的默認值

我們可以在函數定義中使用參數默認值,比如
def funcC(a, b=0):
  print a
  print b
在函數funcC的定義中,參數b有默認值,是一個可選參數,如果我們調用funcC(100),b會自動賦值為0。

 

5.參數默認值的繼承性

下面的程序就會出現很奇怪的現象:
def f(a, L=[]):
    L.append(a)
    returnL

print(f(1))
print(f(2))
print(f(3))
結果:
[1]
[1, 2]
[1, 2, 3]  #結果有繼承性,因為L設置了默認值

 

但是當不設置默認值的時候:

def f(a, L):
    L.append(a)
    returnL

print(f(1))
print(f(2))
print(f(3))

結果:
[1]
[2]
[3]  #結果沒有繼承性,因為L沒有設置了默認值

實際上是可以解釋的,因為,python是解釋性的語言,不像C++那樣,先編譯一邊,把東西准備好,在執行之前,函數已經成為一個很固定的東西。而python卻不一樣,那是解釋性的,程序執行到那個函數定義的地方系統才在表中注冊這個函數,並且對參數的默認值進行賦值,所以才容許你使用變量來賦值。第一次使用之后,我們知道L是函數內部的元素,再一次執行它就跟將前面的定義代碼在copy過 去一樣的。要知道解釋性的語言就是這樣,因為除了默認參數值以外其他的變量(包括參數),都需要從新賦值,所以這個不會顯示出什么不同,倒是默認參數值, 可能繼承上一次的數據。(實際上,其他的變量也會繼承,只是在有一次使用之前都會被從新賦值,只是具有默認值的參數具有特殊性。它時常不會被賦值,這樣, 上一次的數據就會被保存。簡單的說:對函數的幾次連續調用就跟將函數的內容重復放幾遍一樣,他們的變量都有繼承的特性,只是具有默認值的參數的值會繼承上次的數據。

 

6.帶*的參數:用來接受可變數量參數

目前為止,我們要定義一個函數的時候,必須要預先定義這個函數需要多少個參數(或者說可以接受多少個參數)。一般情況下這是沒問題的,但是也有在定義函數的時候,不能知道參數個數的情況(想一想C語言里的printf函數),在Python里,帶*的參數就是用來接受可變數量參數的。看一個例子
def funcD(a, b, *c):
  print a
  print b
  print "length of c is: %d " % len(c)
  print c
調用funcD(1, 2, 3, 4, 5, 6)結果是
1
2
length of c is: 4
(3, 4, 5, 6)
我們看到,前面兩個參數被a、b接受了,剩下的4個參數,全部被c接受了,c在這里是一個tuple。我們在調用funcD的時候,至少要傳遞2個參數,2個以上的參數,都放到c里了,如果只有兩個參數,那么c就是一個empty tuple。

func(*args)  

傳入的參數為以元組形式存在args中,如:

 

func( **kwargs)

傳入的參數為以字典形式存在args中,如:

 

func(*args, **kwargs)

傳入的順序必須和定義順序相同,這里是先不定參數列表,再是關鍵字參數字典,如:

 

7.帶**的參數:

如果一個函數定義中的最后一個形參有 ** (雙星號)前綴,所有正常形參之外的其他的關鍵字參數都將被放置在一個字典中傳遞給函數,比如:
def funcF(a, **b):
  print a
  for x in b:
    print x + ": " + str(b[x])
調用funcF(100, c='你好', b=200),執行結果
100
c: 你好
b: 200
大家可以看到,b是一個dict對象實例,它接受了關鍵字參數b和c。

 

8.有關*和**的最本質的意義:

在python中的函數,我們要注意兩個特點,一個就關鍵字參數,一個就是任意參數。任意參數的本質意義是讓函數能夠接受任意多個參數,它的本質意義是用*args表示一個集合,等到這個參數賦值的時候,它會盡可能的接收它能接受的參數,形成一個集合。

也就是說,實際上,假設函數的形參還是與實參的個數是對應的,而*args的引入,就代表*args,表示有0到任意多個形參。同理**args(他是一個字典集合)。也就是說

def fun(n, *args):
是個函數定義其實就是def fun(n, args[0],args[1],args[2]....).到了函數內部*args就是一個集合。也就是說*這個符號具有拆分的意思,這個意思在另外一個地方就成為了作用了。

一個集合拆分成,分開的幾個參數,而不是一個元素的集合。這里要分清楚,集合是一個對象(不管內部有幾個元素),而是用*拆分后就是若干個對象了

發現沒有,實際上,args就是表達成一個集合,加上*,就表示多個元素了。

實際上:def fun(n,*args):
如果還原到普通函數就是這樣的了:
def fun(n,args):
這是使用它的時候就是這樣的:
fun(12, ["xu", "yong", "quan"])
*args在作為行參的時候,就表示,將這個集合拆分成若干個變量元素。這樣就是:
def fun(n, args[0],args[1],args[2]....).

*args在作為實參(變量)的時候,也是拆分的意思。

 

參考鏈接:http://blog.sina.com.cn/s/blog_6babbcb801018412.html

http://blog.sina.com.cn/s/blog_93b45b0f0100z3et.html

http://www.cnblogs.com/tqsummer/archive/2011/01/25/1944416.html

http://blog.csdn.net/xmnathan/article/details/39156697


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM