Learn day4 函數參數\變量\閉包\遞歸

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))

?

轉載于:https://www.cnblogs.com/NGU-PX/p/11217463.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448209.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448209.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448209.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java 中去除字符串中空格的方法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1、方法分類 str.trim(); //去掉首尾空格str.replace(" ",""); //去除所有空格&#xff0c;包括首尾、中間str.re…

使用重定向的輸入和輸出創建子進程

本主題中的示例演示如何使用控制臺進程中的CreateProcess函數創建子進程。它還演示了一種使用匿名管道重定向子進程的標準輸入和輸出句柄的技術。請注意&#xff0c;命名管道也可用于重定向進程I / O. 所述CreatePipe函數使用SECURITY_ATTRIBUTES結構來創建可繼承句柄讀寫兩個…

手動擋停車時掛檔有技巧

徐小姐來電&#xff1a;我家的汽車要年檢了&#xff0c;前幾天&#xff0c;工作人員幫我把車子開進檢測站去檢測&#xff0c;開回來后停在原位上&#xff0c;然后把鑰匙交給我。我拿鑰匙一點火&#xff0c;車子就突然往前動了&#xff0c;根本沒有時間反應&#xff0c;已經撞到…

LOJ 3156: 「NOI2019」回家路線

題目傳送門&#xff1a;LOJ #3156。 題意簡述&#xff1a; 有一張 \(n\) 個點 \(m\) 條邊的有向圖&#xff0c;邊有兩個權值 \(p_i\) 和 \(q_i\)&#xff08;\(p_i<q_i\)&#xff09;表示若 \(p_i\) 時刻在這條邊的起點&#xff0c;則 \(q_i\) 時刻能到達這條邊的終點。 你需…

線程池概述

線程池 一個線程池的工作線程代表應用程序的高效執行異步回調的集合。線程池主要用于減少應用程序線程的數量并提供工作線程的管理。應用程序可以對工作項進行排隊&#xff0c;將工作與可等待的句柄相關聯&#xff0c;根據計時器自動排隊&#xff0c;并與I / O綁定。 線程池架…

WEB 請求處理二:Nginx 請求 反向代理

上一篇《WEB請求處理一&#xff1a;瀏覽器請求發起處理》&#xff0c;我們講述了瀏覽器端請求發起過程&#xff0c;通過DNS域名解析服務器IP&#xff0c;并建立TCP連接&#xff0c;發送HTTP請求。本文將講述請求到達反向代理服務器的一個處理過程&#xff0c;比如&#xff1a;在…

方向盤的正確駕馭方法

如果問您油門踏板和方向盤哪個與駕駛員最“親密”&#xff0c;您會選擇誰呢&#xff1f;恐怕還是方向盤吧。如果汽車行駛過程中您的雙手同時離開了方向盤&#xff0c;那么事故的隱患也就隨之而來。下面我們就為您全面介紹汽車方向盤的正確使用方法。專家介紹&#xff0c;握方向…

SQL server 2005中無法新建作業(Job)的問題

客戶端是使用企業管理其&#xff08;Management Studio&#xff09;新建job&#xff0c;總是無法創建&#xff0c;查找了很多資料&#xff0c;有的說是需要sp2, 但有的又說不是... ... 沒有時間去研究為什么&#xff0c;但確有一種方法解決&#xff1a;到服務器端去創建job&…

線程池API

線程池API 線程池應用程序編程接口&#xff08;API&#xff09;使用基于對象的設計。以下每個對象都由用戶模式數據結構表示&#xff1a; 池對象是一組可用于執行工作的工作線程。每個進程可以根據需要創建具有不同特征的多個隔離池。每個進程都有一個默認池。清理組與一組回…

WEB 請求處理 一:瀏覽器 請求發起處理

最近&#xff0c;終于要把《WEB請求處理系列》提上日程了&#xff0c;一直答應小伙伴們給分享一套完整的WEB請求處理流程&#xff1a;從瀏覽器、Nginx、Servlet容器&#xff0c;最終到應用程序WEB請求的一個處理流程&#xff0c;前段時間由于其他工作事情的安排&#xff0c;一直…

離合器半聯動探秘

離合器踏板作用是切斷發動機和變速箱之間的動力&#xff0c;有利于起步、變速、和停車。那么如何更好的使用它呢&#xff1f; 離合器的五種狀態示意圖 離合器半聯動的使用方法揭密如下&#xff1a; 離合器半聯動的使用探密之一 將離合器抬到車開始動時你就別再抬了&#xff0c;…

Biztalk Server 2006安裝配置

前段時間收到了來自beta.microsoft.com的BTS20006 Beta2的下載地址&#xff0c;這兩天對它進行了一番安裝配置。下面把一些經過和步驟和大家分享一下&#xff0c;手中有一些去年的Biztalk Server2004版本的培訓資料&#xff0c;里面有11個Lab。需要的朋友請留下mail&#xff0c…

apache 官方 Dubbo 文檔

只是分享、記錄一下 dubbo 的文檔地址&#xff1a;apache 官方 Dubbo 文檔 其頁面內容如下&#xff1a;&#xff08;我是用 chrome 直接右鍵翻譯的&#xff0c;原文檔是英文的&#xff09;

制動踏板是什么?

制動踏板就是腳剎&#xff08;行車制動器&#xff09;的踏板&#xff0c;使運行中的機車、車輛及其他運輸工具或機械等停止或減低速度的動作。制動的一般原理是在機器的高速軸上固定一個輪或盤&#xff0c;在機座上安裝與之相適應的閘瓦、帶或盤&#xff0c;在外力作用下使之產…

CSS Framework 960 Grid System (收)

CSS框架 &#xff1a;960 Grid System 官網&#xff1a;http://960.gs/ 什么是框架&#xff1f;框架是一種你能夠使用在你的web項目中概念上的結構。CSS框架一般是CSS文件的集合&#xff0c;包括基本風格的字體排版&#xff0c;表單樣式&#xff0c;表格布局等等&#xff0c;比…

使用線程本地存儲

線程本地存儲&#xff08;TLS&#xff09;使同一進程的多個線程能夠使用由TlsAlloc函數分配的索引來存儲和檢索線程本地的值。在此示例中&#xff0c;在進程啟動時分配索引。當每個線程啟動時&#xff0c;它會分配一個動態內存塊&#xff0c;并使用TlsSetValue函數在TLS槽中存儲…

發動機的工作原理,你知道嗎?

http://auto.jxedt.com/info/5352.htm 發動機是汽車的動力裝置&#xff0c;性能優劣直接影響到汽車性能&#xff0c;發動機的類型很多&#xff0c;結構各異&#xff0c;以適應不同車型的需要。按發動機使用燃料劃分&#xff0c;可分成汽油發動機和柴油發動機等類別。按發動機汽…

官方文檔: Dubbo 框架設計、模塊說明、依賴關系

以下內容全文轉自 apache 官方 dubbo文檔&#xff1a;http://dubbo.apache.org/en-us/docs/dev/design.html 框架設計 圖片描述&#xff1a; 淺藍色背景的左側區域顯示服務用戶界面&#xff0c;淺綠色背景的右側區域顯示服務提供者界面&#xff0c;中心區域顯示兩個側面界面。…

那些花兒

今天上海下雨了&#xff0c;心緒也變得低落&#xff0c;突然很想念宿舍的姐妹。畢業后就自作聰明地和她們失去了聯系&#xff0c;今天去QQ群遛了一圈。虹結婚了&#xff0c;敏還是活得那么瀟灑&#xff0c;笑也在努力地生活... 人生啊&#xff01;總是在向前走&#xff0c;遇…

CreateRemoteThread函數

CreateRemoteThread函數 創建在另一個進程的虛擬地址空間中運行的線程。 使用CreateRemoteThreadEx函數創建在另一個進程的虛擬地址空間中運行的線程&#xff0c;并可選擇指定擴展屬性。 語法 HANDLE CreateRemoteThread(HANDLE hProcess,LPSECURITY_ATTRI…