您好,登錄后才能下訂單哦!
本篇內容介紹了“Python全棧作用域和閉包怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
# ### return 自定義函數的返回值 """ 概念:return 把函數內部的數據返回到函數的外面,返回到函數的調用處 1.return + 六大標準數據類型 , 除此之外還可以返回函數 或者 是類對象 2.return 在執行時,意味著終止函數,后面的代碼不執行. 3.如果不定義return返回值,默認返回None """ # (1) return + 六大標準數據類型 def func(): # return 111 # return 6.89 # return "你好帥啊,我愛死你樂" # return [1,2,3] # return {"a":1,"b":2} return 1,2,3 # 返回元組 res = func() print(res) # (2) return 在執行時,意味著終止函數,后面的代碼不執行. def func(): print(1) print(2) return 3 print(4) res = func() print(res) def func(): for i in range(5): if i == 3: return 4 print(i) res = func() print(res) # (3) 如果不定義return返回值,默認返回None def func(): pass res = func() print(res) # None # 注意點 打印的數據和返回的數據不是等價的,返回的數據是可以自定義的; res = print(1234) print(res) # None # 模擬+-*/計算器 """ 功能: 完成計算 參數: 2個數字和運算符 返回值: 計算后的結果 """ def calc(num1,num2,sign): if sign == "+": return num1 + num2 elif sign == "-": return num1 - num2 elif sign == "*": return num1 * num2 elif sign == "/": if num2 == 0: return "除數不能為零" return num1 / num2 else: return "抱歉,超出了我的運算范圍." res = calc(3,5,"+") res = calc(3,5,"-") res = calc(3,5,"*") res = calc(3,0,"/") res = calc(3,0,"&") print(res)
# ### 全局變量和局部變量 """ 1.概念 局部變量:在函數內部定義的變量就是局部變量 全局變量:在函數外部定義的變量或者在函數內部使用global關鍵字聲明是全局變量 2.作用域: 局部變量的作用范圍僅僅在函數的內部 全局變量的作用范圍橫跨整個文件 3.生命周期:該變量的作用時長 內置命名空間 -> 全局命名空間 -> 局部命名空間 (開辟空間順序) 內置屬性 > 全局屬性 > 局部屬性 (作用時長:長->短) """ # 1 局部變量 def func(): # 定義一個局部變量 a = 1 # 獲取當前的局部變量 print(a) # 修改一個局部變量 a = 2 print(a) func() # print(a) error # 2.全局變量 # 定義一個全局變量 b = 10 # 獲取當前的全局變量 print(b) # 修改一個全局變量 b = 20 print(b) def func(): print(b) func() # 3.函數內部定義全局變量 def func(): global c c =30 func() print(c) # 4.函數內部修改全局變量 d = 50 def func(): global d d = 51 func() print(d) """ 總結:global的使用 如果當前不存在全局變量,可以在函數內部通過global關鍵字來定義全局變量 如果當前存在全局變量,可以在函數內部通過global關鍵字來修改全局變量 """
# ### 函數名的使用 """ # python中的函數可以像變量一樣,動態創建,銷毀,當參數傳遞,作為值返回,叫第一類對象.其他語言功能有限 """ def func(): print( "我是func函數") # (1)動態創建 a = 1 print(a) a = func a() # (2)動態銷毀 del a # a() # func() # (3)當參數傳遞 def func2(): return "我是func2函數" def func1(f): return f() # "我是func2函數" res = func1(func2) print(res) # (4)作為值返回 def func3(): print( "我是func3函數" ) def func4(f): return f res = func4(func3) print(res) res() print("<===>") # (5)函數名可以作為容器類型數據的元素 lst = [func,func3] for i in lst: i() print("<=========>") # ### __doc__ 或者help查看文檔 def big_chang_cishen(something): """ 功能: 教你怎么吃大腸 參數: 吃的內容 返回值: 是否滿意 """ print("把{}洗一洗".format(something)) print("直接找腸子頭,放嘴里,吸一下") print("擦擦嘴,滿意的放下腸子頭") return "吃完了,真好吃~" big_chang_cishen("生腸子") # 方法一 res = big_chang_cishen.__doc__ print(res) # 方法二 help(big_chang_cishen)
# ### 函數的嵌套 """ 互相嵌套的兩個函數![請添加圖片描述](https://img-blog.csdnimg.cn/f3ab3fd8502e43eebd473306c0e28633.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA54as5aSc5rOh6p645p2e,size_20,color_FFFFFF,t_70,g_se,x_16) : 包裹在外層的叫做外函數,內層的就是內函數 """ def outer(): # inner() def inner(): print("我是inner函數") """""" # (1)內部函數可以直接在函數外部調用么 不行 # inner() # (2)調用外部函數后,內部函數可以在函數外部調用嗎 不行 # outer() # inner() # (3)內部函數可以在函數內部調用嗎 可以 outer() # (4)內部函數在函數內部調用時,是否有先后順序 有的 # 先定義在調用 # 在其他語言中有預加載的機制,提前把函數駐留到內存中,然后再去編譯腳本內容 # python沒有預加載函數的機制,只能先定義在調用; # 外函數是outer 中間函數是inner 最里層是smaller ,調用smaller函數 def outer(): def inner(): def smaller(): print("我是smaller函數") smaller() inner() outer() # LEGB 原則 def outer(): def inner(): def smaller(): print(a) smaller() inner() outer() """ LEGB原則(就近找變量原則) #找尋變量的調用順序采用LEGB原則(即就近原則) B —— Builtin(Python);Python內置模塊的命名空間 (內建作用域) G —— Global(module); 函數外部所在的命名空間 (全局作用域) E —— Enclosing function locals;外部嵌套函數的作用域(嵌套作用域) L —— Local(function);當前函數內的作用域 (局部作用域) 依據就近原則,從下往上 從里向外 依次尋找 """
# ### nonlocal的使用 (用來修改局部變量) """ nonlocal遵循LEGB原則 (1) 它會找當前空間上一層的變量進行修改 (2) 如果上一層空間沒有,繼續向上尋找 (3) 如果最后找不到,直接報錯 """ # (1)它會找當前空間上一層的變量進行修改 def outer(): a = 10 def inner(): nonlocal a a = 20 print(a) inner() print(a) outer() # (2)如果上一層空間沒有,繼續向上尋找 def outer(): a = 20 def inner(): a = 15 def smaller(): nonlocal a a = 30 print(a) smaller() print(a) inner() print(a) outer() # (3)如果最后找不到,直接報錯 """nonlocal 只能修改局部變量,""" """ a = 20 def outer(): def inner(): def smaller(): nonlocal a a = 30 print(a) smaller() print(a) inner() print(a) outer() error """ # (4) 不通過nonlocal 是否可以修改局部變量呢?ok def outer(): lst = [1,2,3] def inner(): lst[-1] = 3000 inner() print(lst) outer()
# ### 閉包函數 """ 互相嵌套的兩個函數,如果內函數使用了外函數的局部變量 并且外函數把內函數返回出來的過程,叫做閉包 里面的內函數叫做閉包函數 是不是閉包? 1.內函數用了外函數的那個局部變量 2.外函數返回內函數 """ # 1.基本語法形式 def zhaoshenyang_family(): father = "馬云" def hobby(): print("我對錢沒有一絲絲的興趣,我不看重錢,這是我爸爸{}說的".format(father)) return hobby func = zhaoshenyang_family() func() print("<==1==>") tup = func.__closure__ print(tup[0].cell_contents) # 馬云 print(tup) print("<==2==>") # 2.閉包的復雜形式 def zhaowanli_family(): gege = "王思聰" didi = "鞋王,高振寧" money = 1000 def gege_hobby(): nonlocal money money -= 500 print("我交朋友不在乎他有沒有錢,反正都沒有我有錢.我就喜歡交女朋友... 錢物還剩下{}".format(money)) def didi_hobby(): nonlocal money money -= 400 print("家里有鞋柜,各式各樣的奢侈鞋,一雙大概20~30萬,錢物還剩下{}".format(money)) def big_master(): return [gege_hobby,didi_hobby] return big_master func = zhaowanli_family() print(func) lst = func() print(lst) # 獲取哥哥函數 gege = lst[0] gege() # 獲取弟弟函數 didi = lst[1] didi() # 3.使用 __closure__ , cell_contents 判定閉包 """如果返回的元組中有數據說明是閉包,誰的生命周期被延長就打印誰""" tup = func.__closure__ print(tup) # 先獲取第一個單元格 cell_contents獲取對象中的內容 func1 = tup[0].cell_contents print("<11111>") """打印閉包函數didi_hobby中,生命周期被延長的屬性""" print(func1.__closure__[0].cell_contents) func1() # 在獲取第二個單元格 cell_contents獲取對象中的內容 func2 = tup[1].cell_contents print("<22222>") """打印閉包函數gege_hobby中,生命周期被延長的屬性""" print(func2.__closure__[0].cell_contents) func2()
# ### 閉包特點 """ 特點:在閉包函數中,內函數使用了外函數的局部變量, 該變量會與內函數發生綁定,延長該變量的生命周期, 持續到腳本執行結束. """ def outer(val): def inner(num): return val + num return inner func = outer(10) res = func(15) print(res) # ### 閉包的意義 """全局變量的作用域大,容易被篡改""" num = 0 def click_num(): global num num += 1 # num = num + 1 print(num) click_num() click_num() click_num() num = 100 click_num() click_num() # 改造,用閉包來實現 """ 閉包的意義: 閉包可以優先使用外函數中的變量,并對閉包中的值起到了封裝保護的作用.外部無法訪問. """ def outer(): x = 0 def click_num(): nonlocal x x += 1 print(x) return click_num click_num = outer() click_num() click_num() click_num() x = 100 click_num() click_num()
def outer(): a = 10 def inner(): a = 20 print(a) inner() print(a) outer() 這里的輸出結果是20 10,嵌套里的兩個a變量互不干擾 列表可以直接可以在內外函數直接傳遞值,修改列表 的時候不需要使用nolocal來修改變量的值。 閉包可以延長局部變量的周期 沒辦法在函數的內部去修改一個全局變量的,必須通過一個global(跟nonlocal一個道理的)
# # 1.定義函數:接收任意個參數,打印其中的最小值 def func(*args): lst = [] for i in args: if isinstance(i , (float,int)): lst.append(i) print(lst) return lst[0] res = func(-100,1,2,423,"sdf") print(res) # 2.定義函數:傳入一個參數n,返回n的階乘(5! = 5*4*3*2*1) def func(n): total = 1 for i in range(n,0,-1): total *= i return total print(func(5)) # 3.寫函數,傳入函數中多個實參(均為可迭代對象如字符串,列表,元祖,集合等) # # 將容器中的每個元素依次添加到新的列表中返回 #例:傳入函數兩個參數[1,2,3] (22,33)最終args為(1,2,3,22,33) # 方法一 def func(*args): lst =[] for i in args: for j in i: lst.append(j) return lst res = func([1,2,3],(5,6,7),"abc") print(res) # 方法二 def func(*args): return list(args) res = func(*[1,2,3],*(5,6,7),*"abc") print(res) # 4.寫函數,用戶傳入要修改的文件名,與要修改的內容,執行函數,修改操作 # 方法一 def func(filename,str1,str2): with open(filename,mode="r+",encoding="utf-8") as fp: strvar = fp.read() print(strvar) res = strvar.replace(str1,str2) with open(filename,mode="w+",encoding="utf-8") as fp: fp.write(res) func("ceshi2.py","內置函數","外置函數") # 方法二 def func(filename,str1,str2): with open(filename,mode="r+",encoding="utf-8") as fp: strvar = fp.read() res = strvar.replace(str1,str2) # print(fp.tell()) fp.seek(0) # 清空 fp.truncate() fp.write(res) func("ceshi2.py","外置函數","內置函數") # 5.寫函數,計算傳入字符串中【數字】、【字母】、【空格] 以及 【其他】的個數 # 方法一 def func(strvar): dic = {"num":0,"word":0,"space":0,"other":0} for i in strvar: if i.isdecimal(): dic["num"] += 1 # dic["num"] = dic["num"] + 1 elif i.encode().isalpha(): dic["word"] += 1 elif i.isspace(): dic["space"] += 1 else: dic["other"] += 1 return dic # strvar = input("請輸入字符串") # print(func(strvar)) """ print("你".isalpha()) # 中文 => False print("你".encode().isalpha()) # 字母 => True print("a".encode().isalpha()) """ # 方法二 def func(strvar): dic = {"num":0,"word":0,"space":0,"other":0} lst = [] for i in range(97,123): lst.append(chr(i)) lst.append(chr(i-32)) for i in strvar: if i in "0123456789": dic["num"] += 1 elif i in lst: dic["word"] += 1 elif i == " ": dic["space"] += 1 else : dic["other"] += 1 return dic # strvar = input("請輸入字符串") # print(func(strvar)) # 6.寫函數,檢查字典的每一個value的長度,如果大于2,那么僅保留前兩個長度的內容,返回處理后的結果. #例:參數為:dic = {"k1": "v1v1", "k2": [11,22,33,44]} def func(dic): if isinstance(dic,dict): for k,v in dic.items(): print(k,v) dic[k] = v[:2] return dic else: return "不是字典" dic = {"k1": "v1v1", "k2": [11,22,33,44]} print(func(dic)) print(func([1,23,42,34,23,4234])) # 7傳入多個容器類型數據,計算所有元素的個數 def func(*args): total = 0 for i in args: print(i) total += len(i) return total res = func("123",[5,6,7],("你好","123423")) print(res) # 改造,不去判斷字符串本身的長度 def func(*args): total = 0 for i in args: print(i) if isinstance(i,str): total += 1 elif isinstance(i,(tuple,list,set,dict)): total += len(i) return total res = func("123",[5,6,7],("你好","123423")) print(res)
“Python全棧作用域和閉包怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。