python函式基礎學習
函式的定義與呼叫:
def 函式名(引數1,引數2):
‘’’函式註釋’’’
print(‘函式體’)
return 返回值
定 義:def關鍵字開關,空格之後接函式名和圓括號,最後冒號結尾
def 是固定且不可變的
函式名:函式名是包含字母、數字、下劃線的任意組合,(不能以數字開頭)
函式呼叫: 返回值 = 函式名 (引數1,引數2)
函式返回值:
1- return的作用:結束一個函式的執行
2- 首先返回值可以是任何的資料型別
3- 函式可以有返回值:如有返回值,必須要用變數接受才有效果
也可以沒有返回值:
- 不寫return 的時候,函式返回值為 None
- 只寫一個return的時候,函式返回值為 None
- return Nonede 時候,函式返回值為None(幾乎不用)
4- return返回一個值(一個變數)
5- return返回多個值(多個變數):多個值之間用逗號隔開,以元組的形式返回
接受:可以用一個變數接受,也可以用多個變數接收(返回幾個就用的幾個變數)
函式的引數:
1- 實參和形參:
形參:是函式定義時候定義的引數
實參:函式呼叫的時候傳進的引數
2- 傳遞多個引數:
可以傳遞多個引數,多個引數之間用逗號隔開。
從傳參的角度上,呼叫函式是傳引數有兩種方式:
- 按照位置傳引數
- 按關鍵字傳引數
用法:1-位置引數必須在關鍵字引數的前面
2-對於一個引數只能賦值一次
3- 預設引數:
用法:為什麼要用預設引數?將變化比較小的值設定成預設引數
定義:預設引數可以不傳,不傳的時候用的就是預設值,如果傳會覆蓋預設值
預設的值是在定義函式的時候就已經確定了
3- 動態引數:
按位置傳值多餘的引數都會有args統一接收,儲存為一個元組(tuple)的形式
按關鍵字傳值接收多個關鍵字引數,由
小結 :
1.定義:def 關鍵詞開頭,空格之後接函式名稱和圓括號()。
2.引數:圓括號用來接收引數。若傳入多個引數,引數之間用逗號分割。
引數可以定義多個,也可以不定義。
引數有很多種,如果涉及到多種引數的定義,應始終遵循位置引數、*args、預設引數、**kwargs順序定義。
如上述定義過程中某引數型別預設,其他引數依舊遵循上述排序
3.註釋:函式的第一行語句應該添加註釋。
4.函式體:函式內容以冒號起始,並且縮排。
5.返回值:return [表示式] 結束函式。不帶表示式的return相當於返回 None
def 函式名(引數1,引數2,*args,預設引數,**kwargs):
"""註釋:函式功能和引數說明"""
函式體
……
return 返回值
python函式進階學習
三元運算子
結果 + if + 條件 + else + 結果
一、名稱空間和作用域
名稱空間的本質:存放著名字與值得繫結關係
名稱空間一共分為三種:
全域性名稱空間
區域性名稱空間
內建名稱空間
三者之間得載入與取值順序:(名稱空間和作用域是分不開的)
載入順序:內建名稱空間(執行前載入)->
>全域性名稱空間(執行中:從上到下載入) ->
>區域性名稱空間(執行中:呼叫才載入)<
取 值 :
在區域性呼叫:區域性名稱空間->全域性名稱空間->內建名稱空間
在全域性呼叫:全域性名稱空間->內建名稱空間
作用域:
為什麼要有作用域的概念:
為了函式內的變數不會影響到全域性
作用域就是作用範圍,按照生效範圍可以分為全域性作用域和區域性作用域
全域性作用域:包含內建名稱空間,全域性名稱空間,在整個檔案的任意位置都能被引用,全 局有效
區域性作用域:區域性名稱空間,只能在區域性 範圍內生效
站在全域性看:使用名字:
如果全域性有用全域性的:如果全域性沒有用內建的
二、函式巢狀與作用域鏈
函式的巢狀呼叫:
1 #函式的巢狀呼叫 2 3 def max2(x,y): 4 5 m = x if x>y else y 6 7 return m 8 9 10 11 def max4(a,b,c,d): 12 13 res1 = max2(a,b) 14 15 res2 = max2(res1,c) 16 17 res3 = max2(res2,d) 18 19 return res3 20 21 22 23 ...max4(23,-7,31,11)...
巢狀定義:定義在內部的函式無法直接在全域性被呼叫
為了保護內部函式,確定內部函式只能在外部函式中被呼叫
def animal(): def tiger(): print(‘ bark ’) print(‘ eat ’) tiger() animal()
函式的作用域鏈:
三、函式名的本質(——記憶體地址)
1- 可以被引用
2- 可以被當作容器型別的元素
3- 可以當作函式的引數和返回值(可以當做普通變數使用)
四、閉包
內部函式包含對外部作用域而非全域性作用名字的引用。(函式對上層域名字的引用)
def func(): name = ‘eva’ def inner(): print(name)
裝飾器
裝飾器的本質:一個閉包函式
裝飾器的功能:在不修改原函式及其呼叫方式的情況下對原函式的功能映象擴充套件
語法糖:
1 import time 2 3 def timer(func): 4 5 def inner(): 6 7 start = time.time() 8 9 func() 10 11 print(time.time() - start) 12 13 return inner 14 15 @timer# ==> func1 = timer(func1)===> 語法糖 16 17 def func1(): 18 19 print(‘in func1’) 20 21 func1()
·開放封閉原則:對擴充套件開放,對修改封閉
1- 對擴充套件是開放的
為什麼要對擴充套件開放呢?
我們說,任何一個程式,不可能在設計之初就已經想好了所有的功能並且未來不做任 何更新和修改。所以我們必須允許程式碼擴充套件,新增新功能。
2- 對修改是封閉的
為什麼要對修改封閉呢?
就像我們剛剛提到的,因為我們寫的一個函式,很有可能已經交付給其他人使用了,如果這個時候我們對其進行了修改,很有可能影響其他已經在使用該函式的使用者。
裝飾器完美的遵循了這個開放封閉原則。
裝飾器的主要功能和固定格式:在不改變函式的呼叫方式的基礎上函式前後新增某些功能。
固定格式:(固定萬能格式)
1 def timer(func): 2 3 4 5 def inner(*args,**kwargs): 6 7 8 9 ...執行函式之前要做的... 10 11 12 13 re = func(*args,**kwargs) 14 15 16 17 ...執行函式之後要做的... 18 19 20 21 return re 22 23 24 25 return inner
帶引數的裝飾器:
def outer(flag): def timer(func): def inner(*args,**kwargs): if flag: print(“執行函式之前要做的”) re = func(*args,**kwargs) if flag: print(“執行函式之後要做的”) return re return inner return timer @outer(False) def func(): print(111) func()
多個裝飾器修飾同一個函式:
def wrapper1(func): def inner(): print(‘wrapper1,before func’) func() print(‘wrapper1,after func’) return inner def wrapper2(func): def inner(): print(‘wrapper2,before func’) func() print(‘wrapper2,after func’) return inner @wrapper1 @wrapper2 def f(): print(‘in f’) f()
遞迴與二分演算法
遞迴:在一個函式裡呼叫這個函式本身
1 import sys 2 3 print(sys.setrecursionlimit(100000))
遞迴實現三級選單:
1 menu = { 2 ‘北京’:{ 3 ‘海淀’:{ 4 ‘五道口’:{ 5 ‘soho’:{}, 6 ‘網易’:{}, 7 ‘google’:{}, 8 }, 9 ‘中關村’:{ 10 ‘愛奇藝’:{}, 11 ‘汽車之家’:{}, 12 ‘youku’:{}, 13 }, 14 ‘上地’:{ 15 ‘百度’:{}, 16 }, 17 ‘昌平’: { 18 ‘沙河’:{ 19 ‘老男孩’:{}, 20 ‘北 航’:{}, 21 }, 22 ‘天通苑’:{}, 23 ‘回龍觀’:{}, 24 }, 25 ‘朝陽’:{}, 26 ‘東城’:{}, 27 }, 28 ‘上海’:{ 29 ‘閔行’:{ 30 ‘人民廣場’:{ 31 ‘炸雞店’:{} 32 }, 33 }, 34 ‘浦東’:{}, 35 }, 36 ‘山東’:{}, 37 } 38 39 def three(dic): 40 for key in dic : 41 print(key) 42 k = input(“>>>>>>>>”) 43 if k in dic: 44 three(dic[k]) 45 three(dic)
二分查詢演算法:
1 l = [ 2,3,5,10,15,16,18,22,26 ] 2 3 def find ( l,aim,start,end ): 4 5 mid = ( end+start ) // 2 6 7 if (l[mid] > aim): 8 9 end = mid 10 11 return find(l,aim,start,end) 12 13 elif (l[mid] < aim): 14 15 start = mid 16 17 return find(l,aim,start,end) 18 19 else: 20 21 return mid 22 23 print( find( l,15,start=0,end=len(1)-1 ) )