一、自定義函數
定義函數時,函數體不執行;只有在調用函數時,函數體才執行。函數的結構:
1. def
2. 函數名
3. 函數體
def func_name(): 函數體
4. 返回值
如果沒有聲明返回值,返回值默認為None
def func_name(): pass return True def func_name(): myString = 'this is to test how to return' return mySting
5. 參數
- 形式參數
- 定義函數時出現的參數,稱之為形式參數,有幾個形參就寫幾個,eg. def func(args1,args2)
- 如果沒有形式參數,就留空
- 實際參數
- 調用函數時傳入的參數,稱之為實際參數,又叫實參, eg. func('kaye',21)
- 默認參數
- 在定義函數時,通過name=value這種形式,指定形參的默認值,這種形參,我們稱之為默認參數,eg. def func(args1, args2 = 'default')
- 默認參數必須放在形參列表的最后,如果有多個默認參數也都放在形參列表最后
- 關鍵字參數,又稱指定參數
- 在調用函數時,通過name=value這種形式,將實參傳遞給指定的形參。這樣的實參,我們稱之為關鍵字參數、或指定參數,
- 通常,實參通過從左到右的位置順序匹配形參;但是,如果傳入了指定參數,優先按參數名稱將實參匹配給形參
- eg. def func(args1,args2), func(args2 = 21,args1 = 'kaye') 和 func(args1 = 'kaye', args2 = 21) 的傳參效果是一樣的
- 動態參數,又稱可變參數
- 在定義函數時,使用*args的形式,意味着可以接收任意多個額外的位置相關的參數到元組中;使用**kwargs的形式,意味着可以接收任意多個額外的關鍵字參數到字典中
- eg. func('kaye','leo','jack')
- eg. func('kaye'=21,'leo'=25,'jack'=30)
- 在調用函數時,使用*args的形式,意味着我們可以在序列args(可以是列表、字符串、元組)中封裝任意多個位置相關的對象,並且在將這個序列args傳遞給函數時,將序列args解包為分開的、單個的參數
- eg. func(*['kaye','leo','jack']),相當於args被賦值為('kaye,'leo','jack'), args[0] = 'kaye', args[1] = 'leo',...
- 序列args中的元素可以是列表、字典、元組等等,由此可以獲得多層嵌套的序列化數據類型
- 在調用函數時,使用**kwargs的形式,意味着我們可以在字典中封裝任意多個關鍵字參數,,並且在將這個字典傳遞給函數時,將字典解包為分開的、單個的參數(鍵值對)
- eg. func(**{'kaye':21,'leo':25,'jack':30})
- kwargs從最外層看是字典,而字典的鍵值對可以是列表、字典、元組等等,由此可以獲得多層嵌套的字典
- 在定義函數時,使用*args的形式,意味着可以接收任意多個額外的位置相關的參數到元組中;使用**kwargs的形式,意味着可以接收任意多個額外的關鍵字參數到字典中
- keyword-only參數
- 在定義函數時,跟在*args或一個單獨的*之后的所有參數(可以有1個也可以有多個),都稱之為keyword-only參數
- 對於這種參數,在調用函數時,必須使用關鍵字參數傳參
- eg1. def f1(a,*b,c) => f1(1,'2,3,c=4)
- eg2. def f2(a,*b,c,d) => f2(1,2,3,4,5,c=6,d=7)
- 萬能參數,即混合模式
- 定義函數時,def func(*args, **kwargs),args接收任意多個位置相關的參數,kwargs接收任意多個關鍵字參數(鍵值對)
- 可以同時接收序列化數據類型(字典、元組、字符串)和字典,作為其傳入參數
- python內部使用以下步驟在賦值前進行參數匹配:
- 通過位置分配非關鍵字參數
- 通過匹配變量名分配關鍵字參數(即調用時的name=value)
- 其他額外的非關鍵字參數分配到*name元組中(即*args)
- 其他額外的關鍵字參數分配到**name字典中(即**kwargs)
- 用默認值分配給未得到分配的參數(即函數定義中的name=value)
6. 補充:
- 函數重新定義(以后再說函數重載)
def f1
def f1
python解釋器從上到下執行命令,當函數被重新定義,調用該函數時會使用重新定義的這個函數
- 調用函數傳入形參時,是傳入了對實參的引用,也就意味着,調用函數時對形參的操作,是直接作用在實參上的,會引起實參的變化
- 全局變量
- 全局變量放在程序最前面,從實際作用上看相當於常量,應該全部大寫
- 全局變量可以被所有函數直接讀取
- 如果要在函數中對全局變量重新賦值,必須在變量名前面加上global
- 如果全局變量是字典/列表,要對字典列表中的元素進行增刪改,則不需要加global,直接按平常代碼寫法書寫即可。這是因為字典和列表是可變類型,每一次賦值和更改,都是在原地修改的!
- 注釋
- 一定要寫注釋,讓別人一看就知道這個函數是在完成什么功能
- 一般在函數定義第一行之后輸入注釋內容,用三個雙引號括起來,"""comment"""
- :param param1:
- :return:...
二、三元運算(三目運算)
對簡單的條件語句,可以用三元運算簡寫。三元運算只能寫在一行代碼里面
# 書寫格式 result = 值1 if 條件 else 值2 # 如果條件成立,那么將 “值1” 賦值給result變量,否則,將“值2”賦值給result變量
examples:
result = 'the result if the if succeeds' if option == True else 'the result if the if fails and falls to the else part'
三、lambda表達式
對於簡單的函數,也存在一種簡便的表示方式,即:lambda表達式
# ###################### 普通函數 ###################### # 定義函數(普通方式) def func(arg): return arg + 1 # 執行函數 result = func(123) # ###################### lambda ###################### # 定義函數(lambda表達式) my_lambda = lambda arg : arg + 1 # 執行函數 result = my_lambda(123)
四、列表解析、字典解析
myList = [1,2,3,4]
newList =[i*2 for i in myList] #經過列表解析后,newList = [2,4,6,8]
myList = [1,2,3,4]
myDic = {i:i*2 for i in myList} #得到字典{1:2,2:4,3:6,4:8}
五、遞歸
利用函數編寫如下數列:
斐波那契數列指的是這樣一個數列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368...
def func(arg1,arg2): if arg1 == 0: print arg1, arg2 arg3 = arg1 + arg2 print arg3 func(arg2, arg3) # 在當前函數定義中調用當前函數,體現了遞歸 func(0,1)
