1.函數描述
# ### 函數 """ (1)函數的定義:功能 (包裹一部分代碼 實現某一個功能 達成某一個目的) (2)函數特點:可以反復調用,提高代碼的復用性,提高開發效率,便于維護管理 """# (3) 函數的基本格式 """ # 函數的定義處 def func():code1....code2....# 函數的調用處 func() """ # 函數的定義處 def func():print("今天是好日子")# 函數的調用處 func()# (4) 函數的命名 """函數的命名 字母數字下劃線,首字符不能位數字 嚴格區分大小且,且不能使用關鍵字 函數命名有意義,且不能使用中文哦駝峰命名法: (1)大駝峰命名法:每個單詞的首字符大寫 (一般在類中起名用這樣的方式, 推薦)mycar => MyCar busstop => BusStop myhouse => MyHouseyoucanyouupnocannobb => YouCanYouUpNoCanNoBb (2)小駝峰命名法:除了第一個單詞首字符不用大寫之外,剩下首字符都大寫 (函數中的命名)mycar => myCar myhouse=>myHousemycar => my_car myhouse => my_house (推薦) """# 函數的定義處 def cheng_fa_biao_99():for i in range(9,0,-1):for j in range(1,i+1):print("{:d}*{:d}={:2d} ".format(i,j,i*j),end="")print()# 函數的調用處 # cheng_fa_biao_99() # cheng_fa_biao_99() # cheng_fa_biao_99() # cheng_fa_biao_99() # cheng_fa_biao_99() # cheng_fa_biao_99() # cheng_fa_biao_99() # cheng_fa_biao_99() # cheng_fa_biao_99() # cheng_fa_biao_99()for i in range(10):cheng_fa_biao_99()
2.函數參數
# ### 函數的參數 : 函數運算時,需要的值 """ 參數:形參: 形式參數 (在函數的定義處)實參: 實際參數 (在函數的調用處)形參:(普通[位置]形參 , 默認形參 , 普通收集參數 , 命名關鍵字參數, 關鍵字收集參數) 實參:(普通實參.關鍵字實參)形參 和 實參 要一一對應 """# (1) 普通形參 # 函數的定義處 hang,lie 普通形參 def small_start(hang,lie):i = 0while i<hang:j = 0while j<lie:# 打印星星print("*",end="")j+=1# 打印換行print()i+=1 # 函數的調用處 3,8 普通實參 small_start(3,8)# (2) 默認形參 hang,lie 在函數定義處給與默認值 """如果給與實參,那么就使用實際參數,如果沒給實參,那么就使用參數的默認值 """ def small_start(hang=10,lie=10):i = 0while i<hang:j = 0while j<lie:# 打印星星print("*",end="")j+=1# 打印換行print()i+=1 # small_start() small_start(4,9)# (3) 普通形參 + 默認形參 """默認形參必須寫在普通形參的后面,語法上有要求""" # 函數的定義處 def small_start(hang,lie=10): # def small_start(hang,lie=10):i = 0while i<hang:j = 0while j<lie:# 打印星星print("*",end="")j+=1# 打印換行print()i+=1 # 函數的調用處 # small_start(3)# small_start(4,8)# small_start() error # 形參實參要一一匹配# (4) 關鍵字實參 """ (1)如果使用關鍵字實參進行函數調用,實參的順序無所謂 """ """ (2)如果定義時是普通形參,調用時是關鍵字實參, 那么這個參數后面的所有調用方式都需要關鍵字實參進行調用 """ def small_start(hang,a,b,c,lie=10): # def small_start(hang,lie=10):i = 0while i<hang:j = 0while j<lie:# 打印星星print("*",end="")j+=1# 打印換行print()i+=1 # 關鍵字實參 hang 和 lie # small_start(lie = 12,hang = 12)# small_start(3,4,5,6,7) small_start(3,c=90,b=7,a=5,lie =14)
?3.收集參數
# ### 收集參數 """ 收集參數:(1) 普通收集參數 * 在函數的定義處專門用來收集那些多余的,沒人要的普通實參,形成一個元組語法:def func(*args) : args => arguments def func(*args):print(args) => 返回的數據類型是元組 """ def func(a,b,c,*args):print(a,b,c)print(args)func(1,2,3,4,5,6,6,7,8,8,8,8,8,9)# 計算任意長度的累加和 def mysum(*args):total = 0for i in args:total += iprint(total) mysum(11,23,45,56,1,2) """ 收集參數:(2) 關鍵字收集參數 ** 在函數的定義處專門用來收集那些多余的,沒人要的關鍵字實參,形成一個字典語法:def func(**kwargs) : kwargs => keyword arguments def func(**kwargs):print(kwargs) => 返回的數據類型是字典 """ def func(a=1,b=2,**kwargs): print(a,b)print(kwargs)# 方法1 func(99,b=99,c=4,d=90,f=78) # 方法2 func(b=99,a=111,c=4,d=90,f=78)# 拼接任意字符串 dictvar = {"monitor"} def func(**kwargs):str1 = ""str2 = ""dictvar = {"monitor":"班長","classflower":"班花"}for k,v in kwargs.items():print(k,v)if k in dictvar:str1 += dictvar[k]+":"+ v + "\n"else: str2 += v + " "print(str1)print("吃瓜群眾:",str2)func(monitor="舒則會",classflower="郭一萌",eatgua1="黃花",eatgua2="李村海")
?5.命名關鍵詞參數
# ### 命名關鍵字參數 """ (1) def func(a,b,*,參數1,參數2....) 在*后面定義的參數就是命名關鍵字參數 (2) def func(*args,參數,**kwargs) 夾在普通收集參數和關鍵字收集參數之間的是命名關鍵字參數 如果是命名關鍵字參數,必須使用關鍵字實參來進行調用賦值 """# 定義方法1 def func(a,b,*,c,d):print(a,b)print(c,d)func(1,2,c=3,d=4)# 定義方法2 def func(*args,c,**kwargs):print(args)print(c)print(kwargs)func(1,2,3,4,a=1,b=2,c=3)# 定義方法3 def func(a,b,*,c=3):print(a,b)print(c) # func(1,2) func(1,2,c=22)# 區別于默認形參 def func(a,b,c=3):print(a,b)print(c) # 三種方式皆可 func(1,2) func(1,2,c=22) func(1,2,22)# ### * 和 ** 的魔術用法 """在函數的定義處:* ** 相當于打包操作 (一個是元組,一個是字典)在函數的調用處:* ** 相當于解包操作 (把里面的元素一個一個拿出來,當成實參調用賦值了) """ # * def func(a,b,c):print(a,b,c)lst = [1,2,3] func(*lst) # 相當于 func(1,2,3) 把列表里面的每一個元素都單獨拿出來當成參數進行函數的調用# ** print('--------->') def func(a,*,b,c,d): print(a)print(b,c,d)dictvar = {"b":2,"c":3,"d":4} func(1,**dictvar) # 相當于 func(1,b=2,c=3,d=4) 把字典里面的每一個鍵值對,都拿出來,變成鍵=值的形式,進行關鍵字實參賦值操作# 擴展 # 函數的定義處def func(a,b,*,c,d): print(a,b)print(c,d) lst = [1,2] dictvar = {"c":3,"d":4} # 函數的調用處 func(*lst,**dictvar)""" 在字典的前面加上一個*號,默認只傳遞鍵. 一個*號 后面可以跟str list tuple set dict 常用的一般就是list 二個** 后面可以跟dict 把鍵值對變成鍵=值得形式進行函數調用. """def func(a,b):print(a,b) dictvar = {"c":3,"d":4} func(*"pa")""" 函數的定義處:參數的定義有順序: 普通形參 -> 默認形參 -> 普通收集參數 -> 命名關鍵字參數 -> 關鍵字收集參數def func(*args,**kwawrgs):這樣的形式定義函數,可以接收到所有種類的參數;pass """# 參數練習: def f1(a, b, c=0, *args, **kw):print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)def f2(a, b, c=0, *, d, **kw):print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)#(一) # f1(1, 2) # a=1,b=2,c=0,args=(),kw={} # f1(1, 2, c=3) #a=1,b=2,c=3,args=(),kw={} # f1(1, 2, 3, 'a', 'b') # a=1,b=2,c=3,args=(a,b),kw={} # f1(1, 2, 3, 'a', 'b', x=99)#a=1,b=2,c=3,args=(a,b),kw={x:99} # f2(1, 2, d=99, ext=None)#a=1,b=2,c=0,d=99,kw={ext:None}#(二) args = (1, 2, 3, 4) kw = {'d': 99, 'x': '#'} # f1(1,2,3,4,d=99,x="#") f1(*args, **kw) #a=1,b=2,c=3,args=(4,),kw={'d':99,x:'#'}#(三) myargs = (1, 2, 3) mykw = {'d': 88, 'x': '#'} f2(*myargs, **mykw) #a=1,b=2,c=3,d=88,kw={x:'#'}#(四) a b 普通形參 c 默認形參 *args 普通收集參數 d 命名關鍵字參數 kw 關鍵字收集參數 def f1(a, b, c=0, *args,d,**kw):print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)print(d)f1(1,2,3, 'a', 'b',d=67, x=99,y=77) #a=1,b=2,c=3,d=67,args=(a,b),kw={,x:99,y:77}
?5.return 返回值
# ### return 函數的返回值,只出現在函數里 """ return 自定義返回值,如果沒有寫return ,默認返回None 功能:把值返回到函數的調用處; (1)return 后面可以返回值 是自定義的. 除了6大標準數據類型之外,還有類 對象 函數 (2)如果執行了return 語句,意味著函數終止,后面的代碼不執行 """ # (1) return 后面可以返回值 是自定義的. 除了6大標準數據類型之外,還有類 對象 函數 def func():# return 1# return 3.14# return 3+4j# return True# return [1,2,3]# return {"a":1,"b":2}pass res = func() # res ={"a":1,"b":2} print(res)res = print(1) print(res)# (2) 如果執行了return 語句,意味著函數終止,后面的代碼不執行def func():print("這句話執行了1")print("這句話執行了2")return 1print("這句話執行了3")print("這句話執行了4") res = func() print(res) print("<============>") def func():for i in range(5):if i == 3:return iprint(i) res = func()# 0 1 2# (3) 計算器小例子 def calc(sign,num1,num2):if sign == "+":res = num1 + num2elif sign == "-":res = num1 - num2elif sign == "*":res = num1 * num2elif sign == "/":if num2 == 0:return "除數不能為0"res = num1 / num2return resprint("<===>") res = calc("+",1,1) res = calc("-",-1,90) res = calc("*",52,10) res = calc("/",52,10) res = calc("/",5200,10) print(res)
?6.函數名的使用
# ### 1.函數名的使用 # 1.函數名是個特殊的變量,可以當做變量賦值 def func():print("函數名可以當成變量使用")abc = 45 abc = func print(abc) abc()# 2.函數名可以作為容器類型數據的元素 def func1():print(1) def func2():print(2) def func3():print(3)lst = [func1,func2,func3] for i in lst:i() # func1() func2() func3()# 3.函數名可以作為函數的參數 def func1(func):func()def func2():print('woshi func2')# func形參接收到了func2這個實參函數,調用func1執行里面的代碼塊.調用func2() func1(func2)print("<===>")# 4.函數名可作為函數的返回值 def func3(func):return funcdef func4():print("woshi func4")# func4這個實參被func接收到 ,執行func3代碼塊內容,直接return func4 ,res接收到了返回值func4 res = func3(func4) res() # func4()# ### 2.__doc__或者help查看文檔 # help(print) res = print.__doc__ print(res)# 如何自定義函數的文檔 # 吃大腸的過程 def eat_big_chang(something):"""功能:模擬吃大腸的過程參數:大腸返回值:吃沒吃完的狀態 """print("我是在模擬{}過程".format(something))print("第一步.找腸子頭")print("第二步.把腸子頭放嘴里")print("第三步.使勁唆")return "擦擦嘴,滿意的放下腸子.吃完了"eat_big_chang("吃大腸")# 方法1 用 函數.__doc__ res = eat_big_chang.__doc__ print(res)# 方法2 print("<===>") help(eat_big_chang)
?7.全局變量與局部變量
# ### 全局變量 與 局部變量 """ 局部變量:定義在函數內部的變量 全局變量:定義在函數外部或者用global關鍵字在函數內部定義的變量作用域: 作用的范圍局部變量的作用域:只限定在函數內部; 全局變量的作用域:橫跨整個文件 """# 1.局部變量的獲取 與 修改 def func():a = 15# 獲取局部變量print(a)# 修改局部變量a = 17print(a) func() # print(a) error a局部變量值限定在函數內部使用;# 2.全局變量的獲取 與 修改 b = 100 # 獲取全局變量 print(b) # 修改全局變量 b += 200 print(b)print("<====>") # 3.在函數內部可以直接獲取全局變量,但是不能直接修改 # 用global關鍵字,修改全局變量 c = 50 def func():global cprint(c)c = 60print(c) func() print(c)# 4.在函數內部可以直接定義一個全局變量 def func():global dd = 90 func() print(d)# 總結: """ global關鍵字 如果函數外部沒有該變量,就是在函數內部定義一個全局變量 global關鍵字 如果函數外部有該變量,那么就是在函數內部修改一個全局變量 global用來修飾全局變量 ; 有就修改,沒有就創建. """
# ### 全局變量 與 局部變量 """ 局部變量:定義在函數內部的變量 全局變量:定義在函數外部或者用global關鍵字在函數內部定義的變量作用域: 作用的范圍局部變量的作用域:只限定在函數內部; 全局變量的作用域:橫跨整個文件 """# 1.局部變量的獲取 與 修改 def func():a = 15# 獲取局部變量print(a)# 修改局部變量a = 17print(a) func() # print(a) error a局部變量值限定在函數內部使用;# 2.全局變量的獲取 與 修改 b = 100 # 獲取全局變量 print(b) # 修改全局變量 b += 200 print(b)print("<====>") # 3.在函數內部可以直接獲取全局變量,但是不能直接修改 # 用global關鍵字,修改全局變量 c = 50 def func():global cprint(c)c = 60print(c) func() print(c)# 4.在函數內部可以直接定義一個全局變量 def func():global dd = 90 func() print(d)# 總結: """ global關鍵字 如果函數外部沒有該變量,就是在函數內部定義一個全局變量 global關鍵字 如果函數外部有該變量,那么就是在函數內部修改一個全局變量 global用來修飾全局變量 ; 有就修改,沒有就創建. """
?8.函數的嵌套
# ### 函數的嵌套 """ 函數之間允許嵌套:嵌套在外層的就是外函數嵌套在內容的就是內函數 """def outer():def inner():print("111")inner()""" (1)內部函數可以直接在函數外部調用么 不行 (2)調用外部函數后,內部函數可以在函數外部調用嗎 不行 (3)內部函數可以在函數內部調用嗎 可以 (4)內部函數在函數內部調用時,是否有先后順序 在定義在調用 python 沒有預加載機制:即不能提前把函數加載到內存當中. """ outer()"""def func():passfunc()int a = 5 cint a = 6 java$a = 67 phpvar a = 89 jsa = 90 python """# 外層是outer函數,里面有inner , inner 中還有smaller ,如果調用smaller?def outer(): def inner():def smaller():print(id)print("我是smaller函數")smaller()inner() outer()# LEGB 原則 (就近找變量原則) """ #找尋變量的調用順序采用LEGB原則(即就近原則) B —— Builtin(Python);Python內置模塊的命名空間 (內建作用域) G —— Global(module); 函數外部所在的命名空間 (全局作用域) E —— Enclosing function locals;外部嵌套函數的作用域(嵌套作用域) L —— Local(function);當前函數內的作用域 (局部作用域) 依據就近原則,從下往上 從里向外 依次尋找 """# 生命周期 """ 內置命名空間中的所有變量 > 全局命名空間中的所有變量 > 局部命名空間中的所有變量 """# 了解 """ # 命名空間 : 劃分一塊區域保存所有數據,以字典的方式存儲(變量與值形成映射關系).一共三種. (1)內建命名空間:解釋器啟動時創建,直到解釋器運行結束,生存周期最長 (2)全局命名空間:文件運行時創建,直到解釋器運行結束,生存周期較長 (3)局部命名空間:函數調用時,里面的局部變量才創建,調用結束后即釋放,生存周期較短 #命名空間的提出是為了劃分和控制變量是否可見,以及生存周期的長短.#命名空間 創建順序:(了解)python解釋器啟動->創建內建命名空間->創建全局命名空間->創建局部命名空間 #命名空間 銷毀順序:(了解)函數調用結束后->銷毀函數對應的局部命名空間數據->銷毀全局命名空間數據->銷毀內建命名空間數據 """""" # 地址相關知識點:-5~正無窮 int浮點型非負數 float相同的布爾值 bool在實數+虛數結構中永遠不相同(只有虛數部分除外) complex相同的字符串 str空元組 tupleid() 用來獲取地址is / is not 針對于地址提出來,用來判斷兩個變量地址是否相同.var1 = 90var2 = 90print(id(var1))print(id(var2)) """
?9.nonlocal
# ### nonlocal 用來修飾局部變量 """ nonlocal 符合LEGB 原則, 就近原則找變量; (1) nonlocal 用來修改局部變量 (2) nonlocal 會不停的尋找上一層空間所對應的值,拿來修改 (3) 如果上一層找不到,繼續向上尋找,再也找不到了,直接報錯; """# (1) nonlocal 只能用來修改局部變量 a = 90 def func():# nonlocal a errora = 80print(a) func()# (2) nonlocal 會不停的尋找上一層空間所對應的值,拿來修改 """通過LEGB原則,可以獲取到上一層空間的值,只能單純的獲取,不能直接修改 如果想要修改 通過nonlocal 加以修飾. """ def outer():a = 20def inner():nonlocal aprint(a)a += 1print(a)inner() outer()# (3) 如果上一層找不到,繼續向上尋找,再也找不到了,直接報錯; nonlocal 只能修飾局部變量 a = 100def outer():a = 100def inner():# a = 110def smaller():nonlocal aa += 10# print(a) smaller()print(a,"<=1=>")inner()print(a,"<=2=>") outer()# (4) 不通過nonlocal 是否可以改變局部變量? 可以! 需要使用列表進行操作; def outer():lst = [100,101,102]def inner():lst[0] += 1inner()print(lst) outer()
?10.閉包函數
# ### 閉包函數 """ 概念:內函數使用了外函數的局部變量, 并且外函數把內函數返回出來的過程,叫做閉包 這個內函數叫做閉包函數 """# (1) 基本語法: def lizuqing_family(): father = "李嘉誠"def father_say():print("{}說了:先定他一個小目標,買一個英國倫敦".format(father))return father_sayfunc = lizuqing_family() # func = father_say print(func) func() #=> father_say()# (2) 閉包函數的升級 """ 內函數使用了外函數的局部變量,外函數的局部變量與內函數發生綁定,延長了該變量的生命周期 """ def liaopingping_family():jiejie = "馬蓉"meimei = "馬諾"money = 1000def jiejie_hobby():nonlocal moneymoney -= 500print("買名牌包包,名牌手表,名牌狗鏈,.....家里的前還剩下%s"%(money))def meimei_hobby():nonlocal moneymoney -= 400print("寧愿在寶馬里面哭,也不愿再自行車上面撒歡.家里的錢還剩下%s"%(money))def big_guanjia():return jiejie_hobby,meimei_hobby # 返回一個元組# return (jiejie_hobby,meimei_hobby)return big_guanjiafunc = liaopingping_family() print(func) tup = func() print(tup) #(<function liaopingping_family.<locals>.jiejie_hobby at 0x000001DCD2877048>, <function liaopingping_family.<locals>.meimei_hobby at 0x000001DCD28770D0>) # 調用 姐姐jiejie_hobby jiejie = tup[0] print(jiejie) #<function liaopingping_family.<locals>.jiejie_hobby at 0x0000026526B49048> jiejie() # 調用 妹妹meimei_hobby meimei = tup[1] meimei() # <function liaopingping_family.<locals>.meimei_hobby at 0x000001DCD28770D0>
?10.閉關函數
# ### 閉包的特點 """內函數使用了外函數的局部變量,外函數的局部變量與內函數發生綁定,延長了該變量的生命周期 """ def outer(val):def inner(num):return num + valreturn innerfunc = outer(10) res = func(5) # func = inner() = num + val = 10 + 5 = 15 print(res) """ func = outer(10) val 接收到10這個值 return inner 因為內函數使用了外函數的局部變量val,val就與內函數發生綁定,延長該變量生命周期,不釋放,等待下一次調用時使用res = func(5) num 接受到5這個值 return num + val return 5 + 10 => return 15 """# ### 閉包的意義 """ 閉包可以優先使用外函數中的變量,并對閉包中的值起到了封裝保護的作用.外部無法訪問. 模擬一個鼠標點擊計數功能: """clicknum = 0 def clickfunc():global clicknumclicknum += 1print(clicknum)# 模擬點擊操作,點擊一次就調用一次 clickfunc() clickfunc() clickfunc() clickfunc() clickfunc() clicknum = 100 clickfunc()# 用閉包函數來進行改造 def clickfunc():x = 0def func():nonlocal xx +=1 print(x)return func clickfunc2 = clickfunc() clickfunc2() # clickfunc2() = func() clickfunc2() clickfunc2() clickfunc2() clickfunc2() x = 100 clickfunc2()
11.閉包的特點
# ### 閉包的特點 """內函數使用了外函數的局部變量,外函數的局部變量與內函數發生綁定,延長了該變量的生命周期 """ def outer(val):def inner(num):return num + valreturn innerfunc = outer(10) res = func(5) # func = inner() = num + val = 10 + 5 = 15 print(res)""" func = outer(10) val 接收到10這個值 return inner 因為內函數使用了外函數的局部變量val,val就與內函數發生綁定,延長該變量生命周期,不釋放,等待下一次調用時使用res = func(5) num 接受到5這個值 return num + val return 5 + 10 => return 15 """# ### 閉包的意義 """ 閉包可以優先使用外函數中的變量,并對閉包中的值起到了封裝保護的作用.外部無法訪問. 模擬一個鼠標點擊計數功能: """clicknum = 0 def clickfunc():global clicknumclicknum += 1print(clicknum)# 模擬點擊操作,點擊一次就調用一次 clickfunc() clickfunc() clickfunc() clickfunc() clickfunc() clicknum = 100 clickfunc()# 用閉包函數來進行改造 def clickfunc():x = 0def func():nonlocal xx +=1 print(x)return func clickfunc2 = clickfunc() clickfunc2() # clickfunc2() = func() clickfunc2() clickfunc2() clickfunc2() clickfunc2() x = 100 clickfunc2()
?11.閉包的特點
# ### 閉包的特點 """內函數使用了外函數的局部變量,外函數的局部變量與內函數發生綁定,延長了該變量的生命周期 """ def outer(val):def inner(num):return num + valreturn innerfunc = outer(10) res = func(5) # func = inner() = num + val = 10 + 5 = 15 print(res)""" func = outer(10) val 接收到10這個值 return inner 因為內函數使用了外函數的局部變量val,val就與內函數發生綁定,延長該變量生命周期,不釋放,等待下一次調用時使用res = func(5) num 接受到5這個值 return num + val return 5 + 10 => return 15 """# ### 閉包的意義 """ 閉包可以優先使用外函數中的變量,并對閉包中的值起到了封裝保護的作用.外部無法訪問. 模擬一個鼠標點擊計數功能: """clicknum = 0 def clickfunc():global clicknumclicknum += 1print(clicknum)# 模擬點擊操作,點擊一次就調用一次 clickfunc() clickfunc() clickfunc() clickfunc() clickfunc() clicknum = 100 clickfunc()# 用閉包函數來進行改造 def clickfunc():x = 0def func():nonlocal xx +=1 print(x)return func clickfunc2 = clickfunc() clickfunc2() # clickfunc2() = func() clickfunc2() clickfunc2() clickfunc2() clickfunc2() x = 100 clickfunc2()
# ### 閉包的特點 """內函數使用了外函數的局部變量,外函數的局部變量與內函數發生綁定,延長了該變量的生命周期 """ def outer(val):def inner(num):return num + valreturn innerfunc = outer(10) res = func(5) # func = inner() = num + val = 10 + 5 = 15 print(res)""" func = outer(10) val 接收到10這個值 return inner 因為內函數使用了外函數的局部變量val,val就與內函數發生綁定,延長該變量生命周期,不釋放,等待下一次調用時使用res = func(5) num 接受到5這個值 return num + val return 5 + 10 => return 15 """# ### 閉包的意義 """ 閉包可以優先使用外函數中的變量,并對閉包中的值起到了封裝保護的作用.外部無法訪問. 模擬一個鼠標點擊計數功能: """clicknum = 0 def clickfunc():global clicknumclicknum += 1print(clicknum)# 模擬點擊操作,點擊一次就調用一次 clickfunc() clickfunc() clickfunc() clickfunc() clickfunc() clicknum = 100 clickfunc()# 用閉包函數來進行改造 def clickfunc():x = 0def func():nonlocal xx +=1 print(x)return func clickfunc2 = clickfunc() clickfunc2() # clickfunc2() = func() clickfunc2() clickfunc2() clickfunc2() clickfunc2() x = 100 clickfunc2()
?12.locals和globals
# ### locals 和 globals """ locals() 獲取當前作用域的所有變量如果locals在函數外:所獲取的是locals(),打印返回值之前的所有內容 如果locals在函數內:所獲取的是locals(),調用之前所有內容 """# 當前作用域在全局范圍 a = 1 b = 2 res = locals() c = 3 print(res)""" # 當前作用域在局部范圍 zz = 90 def func():d = 4f = 5res = locals()g = 6print(res)func() """ """ globals 無論在函數內外,都只獲取全局作用域當中的所有內容如果globals在函數外:所獲取的是globals(),打印返回值之前的所有內容 如果globals在函數內:所獲取的是globals(),調用之前所有內容 """ # 當前作用域在全局范圍 a = 1 b = 2 res = globals() c = 3 print(res)# 當前作用域在局部范圍 ''' aa = 11 bb = 22 def func():d =1 f = 2res = globals()z = 3print(res) cc = 33 func() #res = globals() dd = 4 '''# globals 動態的創建全局變量 """ globals() 返回的是系統的字典,只需要在字典里面添加鍵值對,就可以創建全局變量 字典中的鍵 就是變量名 字典中的值 就是變量所指代的值 """ dic = globals() print(dic) dic["wangwen"] = "風流倜儻,美若天仙,才華橫溢,玉樹臨風" # wangwen = "風流倜儻,美若天仙,才華橫溢,玉樹臨風" print(wangwen)# globals 批量創建全局變量 # 創建p1~p5 5個全局變量 def func():dic = globals()for i in range(1,6):# p1 ~ p5 5個鍵dic["p%d" % (i)] = ifunc() print(p1) print(p2) print(p3) print(p4) print(p5)
# ### locals 和 globals """ locals() 獲取當前作用域的所有變量如果locals在函數外:所獲取的是locals(),打印返回值之前的所有內容 如果locals在函數內:所獲取的是locals(),調用之前所有內容 """# 當前作用域在全局范圍 a = 1 b = 2 res = locals() c = 3 print(res)""" # 當前作用域在局部范圍 zz = 90 def func():d = 4f = 5res = locals()g = 6print(res)func() """ """ globals 無論在函數內外,都只獲取全局作用域當中的所有內容如果globals在函數外:所獲取的是globals(),打印返回值之前的所有內容 如果globals在函數內:所獲取的是globals(),調用之前所有內容 """ # 當前作用域在全局范圍 a = 1 b = 2 res = globals() c = 3 print(res)# 當前作用域在局部范圍 ''' aa = 11 bb = 22 def func():d =1 f = 2res = globals()z = 3print(res) cc = 33 func() #res = globals() dd = 4 '''# globals 動態的創建全局變量 """ globals() 返回的是系統的字典,只需要在字典里面添加鍵值對,就可以創建全局變量 字典中的鍵 就是變量名 字典中的值 就是變量所指代的值 """ dic = globals() print(dic) dic["wangwen"] = "風流倜儻,美若天仙,才華橫溢,玉樹臨風" # wangwen = "風流倜儻,美若天仙,才華橫溢,玉樹臨風" print(wangwen)# globals 批量創建全局變量 # 創建p1~p5 5個全局變量 def func():dic = globals()for i in range(1,6):# p1 ~ p5 5個鍵dic["p%d" % (i)] = ifunc() print(p1) print(p2) print(p3) print(p4) print(p5)
?13.匿名函數
# ### 匿名函數 => lambda 表達式 """ lambda 表達式: 用一句話來表達只有返回值的函數 好處:簡潔,方便,定義函數快速簡單 語法:lambda 參數 : 返回值 """ # 1.無參的lambda表達式 def func():return 123456func = lambda : 123456 res = func() print(res)# 2.有參的lambda表達式 def func(n):return type(n) res = func("1234") print(res)func = lambda n : type(n) res = func([1,2,3]) print(res)# 3.帶有條件判斷的lambda表達式 def func(n):if n % 2 == 0:return "偶數"else:return "奇數"# 4.三目運算符: 用來表達雙項分支 """ 真值 if 條件表達式 else 假值如果條件表達式成立,執行真值如果條件表達式不成立,執行假值 """ n = 11 res = "偶數" if n % 2 == 0 else "奇數" print(res)n = 90 func = lambda n : "偶數" if n % 2 == 0 else "奇數" print( func(n) )# 計算參數中的最大值 def func(m,n):if m>n: return melse:return n print( func(13,9) )func = lambda m,n : m if m>n else n print( func(-90,90) )
?14.遞歸函數
# ### 遞歸函數 """ 遞歸函數:自己調用自己的函數 遞:去 歸:回 一去一回是遞歸遞歸的最大深度:官網說法1000層,但實際996~1000 """# 簡單遞歸 def digui(n):print(n,"<==11==>")if n>0:digui(n-1)print(n,"<==22==>") digui(5)""" 去的過程:n = 5print(5,"<==11==>")5 > 0 digui(5 - 1) digui(4)n = 4print(4,"<==11==>")4 > 0 digui(4 - 1) digui(3)n = 3print(3,"<==11==>")3 > 0 digui(3 - 1) digui(2)n = 2print(2,"<==11==>")2 > 0 digui(2 - 1) digui(1)n = 1print(1,"<==11==>")1 > 0 digui(1 - 1) digui(0)n = 0print(0,"<==11==>")0 > 0 條件不滿足,往下執行print(0,"<==22==>")回的過程: (把剩下的沒走玩的代碼繼續執行)回到上一次函數的調用處第17行,從17行繼續向下執行n = 1 print(1,"<==22==>")回到上一次函數的調用處第17行,從17行繼續向下執行n = 2 print(2,"<==22==>")回到上一次函數的調用處第17行,從17行繼續向下執行n = 3 print(3,"<==22==>")回到上一次函數的調用處第17行,從17行繼續向下執行n = 4 print(4,"<==22==>")回到上一次函數的調用處第17行,從17行繼續向下執行n = 5 print(5,"<==22==>")遞歸函數徹底終止. """""" # 遞歸的最大深度 error def func():func() #[Previous line repeated 995 more times] func() """# 棧幀空間:是為了運行函數所需要開辟的空間 """ (1)沒調用一次函數,就是開辟一個棧幀空間的過程 每結束一次函數,就是釋放一個棧幀空間的過程 遞歸函數就是不停的開辟棧幀空間和釋放棧幀空間的過程(2)回的過程有兩種觸發時機: (1)當最后一層函數全部執行完畢,觸發回的過程,回到上一層函數調用處(2)當遇到return 返回值的時候,觸發回的過程,回到上一層函數調用處(3)如果遞歸層數過大,不推薦使用遞歸,如果使用,務必添加一個跳出的條件,防止內存溢出; """""" # 棧幀空間彼此的數據是隔離的,彼此獨立,各是各的空間 def abc(n)print(n) abc(1) abc(2) """# 計算n的階乘 5! = 5*4*3*2*1 def jiecheng(n):if n<=1:return 1return n * jiecheng(n-1) res = jiecheng(5) print(res)""" 需要先把表達式的值算完之后,再返回# 去的過程 n = 5 return 5 * jiecheng(5 - 1) => 5 * jiecheng(4) n = 4 return 4 * jiecheng(4 - 1) => 4 * jiecheng(3) n = 3 return 3 * jiecheng(3 - 1) => 3 * jiecheng(2) n = 2 return 2 * jiecheng(2 - 1) => 2 * jiecheng(1) n = 1 n <= 1 滿足 return 1# 回的過程 n = 2 return 2 * jiecheng(2 - 1) => 2 * jiecheng(1) => 2 * 1 n = 3 return 3 * jiecheng(3 - 1) => 3 * jiecheng(2) => 3 * 2 * 1 n = 4 return 4 * jiecheng(4 - 1) => 4 * jiecheng(3) => 4 * 3 * 2 * 1 n = 5 return 5 * jiecheng(5 - 1) => 5 * jiecheng(4) => 5 * 4 * 3 * 2 * 1 最后直接 return 5 * 4 * 3 * 2 * 1 = 120 """ print(jiecheng(1))
?