歡迎加入Linux_Python學習羣html
羣號:478616847python
目錄:web
函數式編程編程
傳參與返回值數組
遞歸閉包
匿名函數
ssh
高階函數ide
內置函數函數式編程
在第三章,咱們引入新的概念函數,在以往的代碼編寫中咱們都是用的過程式編程,函數式編程的特色將過程式編程變成易於管理調用的小模塊,函數
讓重複的代碼能夠反覆的調用,大大減小代碼量,懶惰即美德
建立函數
一個函數式由關鍵字 def ,與函數名與括號冒號,和括號中的參數組成,當想要執行函數的時候只須要寫上函數名加括號便可
格式: def function (parameter) 下面就建立一個函數
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 #建立函數 5 def print_str(): 6 print("Hello World") 7 8 #調用函數 9 print_str()
變量的做用域
咱們看一個例子,在下面代碼中咱們先把變量 a=「haha」 而後在函數中把 a=「heihei」 最後執行這個函數,並輸出變量a的結果
咱們發現爲何a不等於 "heihei",而是咱們以前賦值的 「haha」 這個現象咱們立刻揭祕
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 a = "haha" 6 7 #建立函數 8 def print_str(): 9 a = "heihei" 10 print("Hello World") 11 12 #調用函數 13 print_str() 14 print("我是變量a:",a)
全局變量與局部變量
很明顯變量的做用域就是變量在哪個範圍內生效,若是出了這個範圍則沒法使用
全局變量:一般全局變量存活在腳本運行結束,而且全部的函數均可以訪問它
局部變量:只能局部變量所在的函數內部調用,而且除非把局部變量聲明成全局變量不然,其餘函數均沒法調用,而且局部變量
當所在的函數執行完成後就不存在了
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 a = "haha" 6 7 #建立函數 8 def print_str(): 9 a = "heihei" 10 print("我是局部變量a:",a) 11 12 13 #調用函數 14 print_str() 15 print("我是全局變量a:",a)
global
global就是能夠把局部變量變成全局變量的,若是被聲明的局部變量名與全局變量名同樣的話,那麼局部變量會覆蓋全局變量,切
使用global聲明變量須要在變量以前聲明不然python會告訴你,你須要在 a 前面聲明
報錯提示:SyntaxWarning: name 'a' is assigned to before global declaration global a
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 a = "haha" 5 6 #建立函數 7 def print_str(): 8 global a 9 a = "heihei" 10 print("我是局部變量a:",a) 11 12 #調用函數 13 print_str() 14 print("我是全局變量a:",a)
傳參
函數用起來比較簡單也容易理解,可是參數的變化就比較多了,在函數括號內就是參數,參數能夠接收字符串,數字,也能夠接收字典和列表
而且在調用的時候,咱們還能夠指定給哪一個參數賦什麼值
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 #建立函數 5 def print_str(Name,Age,Aender): 6 print(''' 7 Name:%s 8 Age:%s 9 Aender:%s 10 '''%(Name,Age,Aender)) 11 12 #用戶輸入 13 in_name = input("請輸入你的名字:") 14 in_age = input("請輸入你的年齡:") 15 in_aender = input("請輸入你的性別:") 16 17 #固定位置傳參 18 print_str(in_name,in_age,in_aender) 19 print("----------------------------------") 20 21 #不固定位置傳參 22 print_str(in_name,Aender=in_aender,Age=in_age)
當咱們想要傳入列表或者字典時須要怎麼辦?
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 def print_str(lists): 5 if type(lists) == list: 6 print(''' 7 Name:%s 8 Age:%s 9 Aender:%s 10 '''%(lists[0],lists[1],lists[2])) 11 else: 12 print(''' 13 Name:%s 14 Age:%s 15 Aender:%s 16 '''%(lists["name"],lists["age"],lists["aenber"])) 17 18 #傳入列表 19 userlist = ["Ben","22","Man"] 20 print_str(userlist) 21 22 print("----------------------------------") 23 #傳入字典 24 userdict = {"name":"Ben","age":"022","aender":"Man"} 25 print_str(userlist)
默認參數
在函數中還能夠設置默認參數,默認參數的意思是這個參數你能夠傳值也能夠不傳值,當不傳值的時候這個參數就等於默認值
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 def print_str(lists,Country="China"): 5 if type(lists) == list: 6 print(''' 7 Name:%s 8 Age:%s 9 Aender:%s 10 country:%s 11 '''%(lists[0],lists[1],lists[2],Country)) 12 else: 13 print(''' 14 Name:%s 15 Age:%s 16 Aender:%s 17 country:%s 18 '''%(lists["name"],lists["age"],lists["aenber"],Country)) 19 20 #傳入列表 21 userlist = ["Ben","22","Man"] 22 print_str(userlist) 23 24 print("----------------------------------") 25 #傳入字典 26 userdict = {"name":"Ben","age":"022","aender":"Man"} 27 print_str(userlist,"America")
非固定參數
非固定參數的意義在於能夠接收任意個值,在你的函數不肯定用戶想傳入多少個值的時候使用,固然在調用有隻有非固定參數的函數的時候咱們能夠不傳參數。
非固定參數分一個*和兩個*,*args會把傳入的參數變成元祖,**kwargs把傳入的參數變成字典,固然*ages能夠是別的名稱,可是在規範中最好使用*args,和**kwargs
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 def print_str(*args,**kwargs): 5 print("我是*",args) 6 print("我是**",kwargs) 7 8 #傳入列表 9 userlist = ["Ben","22","Man"] 10 print_str(userlist,"America") 11 print("----------------------------------") 12 #傳入字典 13 print_str(A = "1",B = "2")
既然形參能夠帶*和**,那麼實參也是能夠帶*和**,那麼*就是配合列表使用的,**就是配合字典的!
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 def print_str(*args,**kwargs): 5 print("我是*",args) 6 print("我是**",kwargs) 7 8 #傳入列表 9 userlist = ["Ben","22","Man"] 10 print_str(*userlist) 11 12 print("----------------分隔符----------------") 13 14 #傳入字典 15 userdict = {"name":"Ben","age":"022","gender":"Man"} 16 print_str(**userdict) 17 18 解參
實參帶*就會把列表分解成 "Ben","22","Man" 一個一個單獨的元素傳入函數,而**會把字典分解成name="Ben",age="022",gender="Man"
這種鍵值對傳入函數。
形參與實參
形參:
變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。所以,形參只在函數內部有效。函數調用結束返回主調用
函數後則不能再使用該形參變量
實參:
能夠是常量、變量、表達式、函數等,不管實參是何種類型的量,在進行函數調用時,它們都必須有肯定的值,以便把這些值傳送給形參。所以
應預先用賦值,輸入等辦法使參數得到肯定值
注!當普通參數和默認參數和非固定參數結合使用的時候,要遵循一個順序,普通參數在默認參數前面,默認參數在非固定參數前面
返回值
在正常使用函數的時候,函數是能夠把函數內部處理的結果返回給函數調用者的,在沒有返回值得函數中會保留None傳給函數調用者,返回值能夠返回序列等
在函數執行的時候遇到return函數會中止執行,並返回結果
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 #建立函數 5 def print_str(Age): 6 if int(Age) <= 30: 7 return "你才%s啊!真年輕"%(Age) 8 else: 9 return "你都%s啦!老傢伙"%(Age) 10 11 in_age = input("請輸入你的年齡:") 12 word = print_str(in_age) 13 print(word)
嵌套函數
在函數內部也能夠寫函數,這樣就是外層函數套着內側函數,這種形式稱之爲嵌套函數,同理由於做用域的關係嵌套函數只能內部調用
return unction_2(stra)+"我是第二層\n" 就等於先 c = unction_2(stra) 而後 return c+"我是第二層\n"
1 def unction(stra): 2 def unction_2(stra_2): 3 return stra_2+"我是第三層\n" 4 return unction_2(stra)+"我是第二層\n" 5 6 r_str = unction("") 7 print(r_str+"我是第一層")
前面已經介紹了函數相關的知識,在函數中,函數能夠調用其餘的函數,而且函數還能夠調用自身,利用這種特性咱們能夠完成一些特定的
操做,這種函數調用自身的形式就是遞歸
def recursion() :
return recursion()
在遞歸中不能像上面兩行同樣一直調用自身,這樣一會程序就會崩潰,由於它永遠的在調用就跟while死循環同樣出不去,因此遞歸也須要進
判斷給它出口
例子:階乘
什麼是階乘,階乘就是給一個天然數N,而後計算N的階乘那麼 N = 1x2x3x4....N ,這個就是階乘,咱們能夠把它到過來看,
N = N x (n-1) x (n-2) x (n-3) ...... 1 一直乘到括號中的值等於1,既然知道了階乘是什麼,那麼咱們來寫一個程序實現它
1 def factorial(n): 2 for i in range(1,n): 3 n *= i 4 return n 5 c = factorial(4) 6 print(c)
剖析:上面的例子首先把n=4傳入進去,而後經過 for i in range(1,4)讓i分別等於1,2,3,而後進行 n*=i,咱們能夠看出這個for循環是循環3次的
第一次(n = n*i) n = 4*1 ,此時n仍是等於4
第二次(n = 4*i) n = 4*2 此時n = 8
第三次(n = 8*i) n = 8*3 此時n等於24
此時for循環了3次因此結束了,經過return把n的結果返回,因此最終結果算出 4的階乘等於24
遞歸版本
下面看遞歸版本的階乘
1 def factorial(n) : 2 if n == 1: 3 return 1 4 else: 5 return n * factorial(n-1) 6 c = factorial(4) 7 print(c)
剖析:
首先c = factorial(4)開始執行函數,而後進行第一次判斷 n == 1,顯然第一層n不等於1,而後碰到return n * factorial(n-1),碰到return原本是要返回的,可是 factorial(n-1)
有調用了factiorial這個函數,所以進入了第二層
第二層由於上一層傳入的參數是n-1,因此第二層的n是等於3的,而後判斷,這一層的n也不等於1,而後又進入第三層
第三層n等於2,而後判斷這一層的n還不等於1,而後又進入第四層
到第四層的時候這時的 n就等於1,因此觸發了 return 1 再也不調用函數了,因此就開始返回
返回第三層 return n * factorial(n-1) , 此時factorial(n-1) 就等於第四層return上去的1,因此第三層返回時就等於return n * 1(return 2 * 1),而且第三層n是等於2的
返回第二層factorial(n-1)就等於第三層return上去的2,而且第二層n是等於3的,return 3 * 2
返回第一層factorial(n-1)就等於第二層return上去的6,而且第一層n是等於4的,return 4 * 6
到此爲止遞歸執行完畢,c就等於 4 * 6 c=24
匿名函數也叫lambda函數,函數沒有具體的名稱。語法:function name= lambda args(多個參數用逗號隔開): Expression(表達式,表達式的結果就是返回值)
先來看一個最簡單例子:
1 #普通函數 2 def func(arg1,arg2): 3 return arg1-arg2 4 5 #lambda函數 6 func_2 = lambda arg1,arg2: arg1-arg2 7 8 #傳參執行 9 print(func(5,4)) 10 print(func_2(5,4))
有認識,這個匿名函數和普通函數沒有什麼區別麼,其實匿名函數就像三元運算同樣,而且可以用lambda函數有幾大優點
一、在一些不會再別的地方調用的函數,咱們可使用匿名函數,而且這樣簡化了代碼,看起來更加整潔。
二、lambda函數將會搭配一些內置函數來使用(下面會涉及到)
在上面的示例中知道了函數能夠調用函數自己,這種形式稱之爲遞歸,那麼還能夠將函數做爲參數返回,這種形式就稱之爲閉包
閉包最大的好處就是即用即調,閉包對於安裝計算,隱藏狀態,以及在函數對象和做用域中隨意地切換是頗有用的!
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 def func(rate): 4 count = [0] 5 def add_func(arg): 6 count[0] +=1 7 print("第%s次調用"%count[0]) 8 arg = arg - arg*rate 9 return arg 10 return add_func 11 12 closure = func(0.03) 13 print(closure(1000)) 14 print(closure(1100)) 15 print(closure(1200))
例子中作了一個減去手續費後返回餘額的功能,首先執行了func函數,將利率封裝了進去,而後,func函數把它內部的函數進行了進行了返回
要知道當函數不加括號的時候是不執行的!,因此此時closoure就是 add_func 函數的內存地址,當想要使用這個功能的時候,直接把closoure加括號
並傳入值便可執行。而且能夠看到的是在全局做用域中執行,隨時能夠切換到局部做用域。
函數能夠用來當作返回值,能夠用調用本身自己,高階函數就是函數的參數把另外一個函數做爲參數,這種函數就稱之爲高階函數。
1 def func_1(num): 2 return num+1 3 4 def func_2(num): 5 return num-1 6 7 def func_main(num,func): 8 # 能夠簡寫成return func(num) 9 results = func(num) 10 return results 11 12 results = func_main(10,func_1) 13 print(results) 14 print(func_main(10,func_2))
編寫高階函數,就是讓函數的參數可以接收別的函數。
內置函數就是python中內置的一些方法,內置函數官方介紹請猛戳這裏
內置函數使用方法示例,詳細介紹請參考
1 # !/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 #返回數字的絕對值。 參數能夠是整數或浮點數。 若是參數是複數,則返回其大小。 5 print(abs(-1.11)) 6 7 #傳入一個可被循環的元素,若是這個元素中有一個爲False則都爲假 8 # 0 空值 False 都爲假 9 print(all([1,2,3])) 10 11 #與all相反,只有一個爲真,則爲真; 12 print(any([0,2,False])) 13 14 #這個函數跟repr()函數同樣,返回一個可打印的對象字符串方式表示。當遇到非ASCII碼時 15 #就會輸出\x,\u或\U等字符來表示。與Python 2版本里的repr()是等效的函數。 16 print(ascii("dsads"),ascii(66),ascii('b\23')) 17 18 #將十進制轉換爲二進制; 19 print(bin(10)) 20 21 #返回布爾值,即True或False之一,若是參數爲false或省略,則返回False; 不然返回True。 22 print(bool(1)) 23 24 #根據傳入的參數建立一個新的字節數組 25 #若是傳入字符串必須給出編碼 26 print(bytearray('你好','utf-8')) 27 #當source參數是一個可迭代對象,那麼這個對象中的元素必須符合大於0 小於256 28 print(bytearray([256,1,2])) 29 30 #返回一個的「bytes」對象,返回bytes類型 31 bytes('中文','utf-8') 32 33 #檢查對象是否能夠被調用 34 def func(): 35 pass 36 print(callable(func)) 37 38 #返回整數所對應的Unicode字符,chr(97)返回字符串'a',而chr(8364)返回字符串'€'。 39 print(chr(126)) 40 41 #是用來指定一個類的方法爲類方法,類方法能夠不實例化直接調用 42 class A: 43 @classmethod 44 def B(cls,arg1,): 45 print(arg1) 46 A.B(1) 47 A().B(1) 48 49 #將源編譯爲代碼或者AST對象。代碼對象可以經過exec語句來執行或者eval()進行求值。 50 #源能夠是正常字符串,字節字符串或AST對象。 51 expr = "5+5-1" 52 obj = compile(expr,"","eval") 53 print(eval(obj)) 54 55 #返回值爲real + imag * j的複數或者轉化一個字符串或數爲複數。若是第一個參數爲字符串,則不須要指定第二個參數。 56 print(complex(1, 2)) 57 print(complex(1)) 58 print(complex("1+2j")) 59 60 61 62 # 參數是一個對象和一個字符串。 該字符串必須是對象屬性之一的名稱。 63 class A: 64 def a1(self): 65 print("a1") 66 def a2(self): 67 print("a2") 68 69 obj = A 70 print(dir(obj)) 71 delattr(obj, "a1") 72 print(dir(obj)) 73 74 #dir 返回對象中的方法 75 strs="aaa" 76 print(dir(strs)) 77 78 #返回兩個數值的商和餘數 79 print(divmod(7,3)) 80 81 #用於遍歷序列中的元素以及它們的下標 82 print(enumerate([1,2,3]))#返回的是可迭代的對象 83 for i,j in enumerate(('A','B','C')): 84 print(i,j) 85 86 #將字符串str當成有效的表達式來求值並返回計算結果。 87 print(eval("1+2+3")) 88 print(eval("False or True")) 89 90 #字符串str當成動態語句塊執行並返回結果 91 exec('a=1+2+3') 92 print(a) 93 94 #使用指定方法(方法,函數),過濾可迭代對象的元素 95 def add(arg): 96 return arg > 3 97 98 for i in filter(add,[1,2,3,4,5]): 99 print(i) 100 101 #浮點型 102 print(float(11)) 103 104 #格式化顯示 更多方法請參考官方說明 105 print('{:,.2f}'.format(111111)) 106 107 #根據傳入的參數建立一個新的不可變集合 108 a = frozenset([1,2,3,4,5]) 109 print(a) 110 111 #獲取對象的屬性值 112 class A(): 113 def __init__(self,): 114 self.name = "123" 115 b = A() 116 print(getattr(b,'name')) 117 118 #返回當前做用域內的全局變量和其值組成的字典 119 print(globals()) 120 121 #檢查對象是否含有屬性 122 class A(): 123 def __init__(self,): 124 self.name = "123" 125 b = A() 126 print(hasattr(b,'name')) 127 128 #哈希值計算 129 #在當前環境中是惟一的 130 print(hash('Hello')) 131 132 #help幫助 133 def funcs(args): 134 """ 135 Function description 136 :param args: args = list 137 :return: 138 """ 139 pass 140 print(help(funcs)) 141 142 #轉換16進制 143 print(hex(44)) 144 145 #顯示對象的標識符 146 print(id("123")) 147 148 #input標準輸入 149 s = input("user name:") 150 print(s) 151 152 #int返回整數 153 print(int(1.2)) 154 print(int("2")) 155 156 #判斷對象是不是類或者類型元組中任意類元素的實例 157 print(isinstance("1",int)) 158 print(isinstance(1.1,(int,float))) 159 160 161 #判斷類是不是另一個類或者類型元組中任意類元素的子類 162 print(dir(str)) 163 print(issubclass(bytearray,str)) 164 print(issubclass(bool,int)) 165 166 #根據傳入的參數建立一個新的可迭代對象 167 a = iter('12345') 168 print(next(a)) 169 print(next(a)) 170 171 #返回對象的長度len 172 a = [1,2,3,4] 173 174 #轉換列表 175 print(list("abcd")) 176 177 #返回當前做用域內的局部變量和其值組成的字典 178 def A(): 179 print(locals()) 180 s = 1 181 print(locals()) 182 A() 183 184 #使用指定方法去做用傳入的每一個可迭代對象的元素,生成新的可迭代對象 185 def add(x): 186 return x+100 187 lists = [1,2,3,4] 188 for i in map(add,lists): 189 print(i) 190 191 #max:返回最大值 192 print(max(1,2,3)) 193 print(max([1,2,3,4])) 194 195 #在進行切片並賦值數據時,不須要從新copy原列表數據,能夠直接映射原數據內存; 196 s = memoryview(b'abcd') 197 print(s[1]) 198 199 #返回最小值 200 print(min(1,2,3)) 201 print(min([2,3])) 202 203 #返回可迭代對象中的下一個元素值 204 a = iter('1234') 205 print(next(a)) 206 207 #建立一個新的object對象(新式類) 208 class B(object): 209 pass 210 211 #轉化成8進制數字符串 212 print(oct(10)) 213 214 #open文件操做 215 file = open('test.txt',encoding="utf-8") 216 217 #ord:返回Unicode字符對應的整數 218 print(ord("A")) 219 220 #冪運算 221 222 print(pow(2,3)) 223 224 #標準輸出 225 print() 226 227 #property:標示屬性的裝飾器 228 #類中使用具體方法請百度,或者等待後續更新 229 property 230 231 #range:根據傳入的參數建立一個新的range對象 232 range(10) 233 range(1,10) 234 235 """repr()函數獲得的字符串一般能夠用來從新得到該對象,repr()的輸入對python比較友好。 236 一般狀況下obj==eval(repr(obj))這個等式是成立的。""" 237 obj='Python' 238 print(eval(repr(obj))) 239 240 241 #翻轉序列 242 a = reversed([1,2,3,4,5]) 243 print(list(a)) 244 245 #round:對浮點數進行四捨五入求值 246 print(round(1.5)) 247 248 #set 轉換成集合 249 print(set([1,2,3])) 250 251 #setattr:設置對象的屬性值 252 class A(): 253 def __init__(self,age): 254 self.age = age 255 s = A(11) 256 print(s.age) 257 setattr(s,'age',22) 258 print(s.age) 259 260 #根據傳入的參數建立一個新的切片對象 261 c1 = slice(3) 262 c2 = slice(2,4) 263 c3 = slice(0,5,2) 264 s = [1,2,3,4,5,6] 265 print(s[c1]) 266 print(s[c2]) 267 print(s[c3]) 268 269 270 #排序,返回一個新的列表默認按字符ascii碼排序 271 a = [4,3,2,1,7] 272 print(sorted(a)) 273 274 #標示方法爲靜態方法的裝飾器 275 class B(object): 276 def __init__(self,age): 277 self.age = age 278 279 @staticmethod 280 def hello(args): 281 print(args) 282 283 B.hello("Hello World") 284 285 #字符串類型 286 print(str(123)) 287 288 #求和 289 print(sum([1,2,3,4])) 290 291 #根據傳入的參數建立一個新的子類和父類關係的代理對象 292 class A(object): 293 def __init__(self): 294 print("我是 A Clase") 295 296 class B(A): 297 def __init__(self): 298 print("我是 B Class") 299 super().__init__() 300 b = B() 301 302 #元祖 303 tuple([1,2,3,4]) 304 305 306 #type 返回對象的類型 307 print(type([1])) 308 print(type("1")) 309 310 #返回當前做用域內的局部變量和其值組成的字典,或者返回對象的屬性列表 311 def func(): 312 print(vars()) 313 s = 1 314 print(vars()) 315 func() 316 317 #聚合傳入的每一個迭代器中相同位置的元素,返回一個新的元組類型迭代器 318 list1 = [1,2,3] 319 list2 = ["A","B","C","D"] 320 print(zip(list1,list2)) 321 for i in zip(list1,list2): 322 print(i) 323 324 #__import__:動態導入模塊 325 __import__
做者:北京小遠
出處:http://www.cnblogs.com/bj-xy/ 本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。