基本格式: python
def 函數名(形參):git
函數體(代碼塊)安全
函數名(實參)閉包
定義一個簡單的函數並調用它:app
1 def app(): 2 print("這只是在構建最基本的函數格式") 3 print("函數的功能並不僅是打印內容") 4 print("函數的做用是封裝功能,裏面什麼都能寫") 5 6 app()
return 執行完函數以後. 咱們可使用return來返回結果.當函數執行到return以後,結束此函數,不在繼續執行 return 能夠返回多個值,用元組表示函數
1 def app(): 2 print("這只是在構建最基本的函數格式") 3 print("函數的功能並不僅是打印內容") 4 print("函數的做用是封裝功能,裏面什麼都能寫") 5 return '基本格式', '封裝功能' 6 print(app())
若是return什麼都不寫 或者 乾脆不寫return .那麼返回的就是Nonespa
若是return後面寫了一個值. 則調用者能夠接收一個結果code
若是return後面寫了多個結果, 則調用者能夠接收一個tuple, 調用者能夠直接解構成多個變量對象
形參:blog
位置參數: 按照位置順序給函數建立參數
1 def yue(fangshi, age): # 形參 2 print("打開手機") 3 print("打開%s" % fangshi) 4 print("找一個漂亮的妹子") 5 print("年齡最好是%s" % age) 6 print("出來約一約") 7 8 yue("探探", 38) 9 yue("陌陌", 26)
默認值參數: 指定參數的值,若是傳參是不輸入值,則使用默認值
1 def regist(id, name, sex="男"): 2 print("錄入學生信息:id是%s, 名字是%s, 性別是:%s" % (id, name, sex)) 3 4 regist(1, "大陽哥") 5 regist(2, "徐衛星") 6 regist(3, "毛尖妹妹", "女")
位置參數和默認值參數混合使用: 能夠把上面兩種參數混合着使用. 也就是說在調用函數的時候便可以給出位置參數, 也可 以指定參數的默認值.
實參:
位置參數: 按照位置給形參賦值
關鍵字參數: 按照名稱給形參賦值
混合參數: 先用位置參數, 再用關鍵字參數
1 def gn(name, age, address, id, sex, hobby): 2 print("人的名字叫%s, 年齡:%s, 地址:%s, id是:%s, 性別:%s, 愛好是:%s" % (name, age, address, id, sex, hobby)) 3 gn("太白", 58, "保定", 1, "不詳", "女") # 位置參數 4 gn(id=1, name="太白", address="保定", hobby="女", age=58, sex="不詳") # 關鍵字(形參)參數 5 gn("太白", 58, "保定", id="3", sex="女", hobby="不詳")
*args 動態傳參 位置傳參
def chi(*food): print("我要吃", food) chi("包子", '饅頭', '米飯', '小龍蝦', '黃燜雞', '酸菜魚')
示例:傳入任意整數,求全部數的和
def num(*digit): sum = 0 for i in digit: sum = sum + i return sum print(num(1,2,3,4,5,6,7))
**kwargs 動態傳參 關鍵字傳參
def app(**games): print(games) app(free_game ='消消樂', dongzuo_game = "格鬥之王", jingji_game = "王者榮耀", yizhi_game = '數獨')
當*args 和 **kwargs一塊兒使用時,什麼東西都能傳入
def func(*args,**kwargs): print(args) print(kwargs) func('哈士奇', '金毛', '薩摩', name='y',age=22,sex='nan')
參數接收順序: 位置參數 , *args , 默認值參數 , **kwargs
內置命名空間: 存放python解釋器爲咱們提供的名字, list, tuple, str, int這些都是內 置命名空間
全局命名空間: 咱們直接在py⽂件中, 函數外聲明的變量都屬於全局命名空間
局部命名空間: 在函數中聲明的變量會放在局部命名空間
加載順序: 內置命名空間 , 全局命名空間 , 局部命名空間
取值順序: 局部命名空間 , 全局命名空間 , 內置命名空間
全局做用域: 包含內置命名空間和全局命名空間. 在整個文件的任何位置均可以使用(遵循 從上到下逐行執行).
局部做用域: 在函數內部可使用.
做用域命名空間:
全局做用域: 內置命名空間 + 全局命名空間
局部做用域: 局部命名空間
globals() 查看全局做用域中的名字
locals() 查看局部做用域中的名字
a = 10 def func(): a = 40 b = 20 def abc(): print("哈哈") print(a, b) # 這⾥使⽤的是局部做⽤域 print(globals()) # 打印全局做⽤域中的內容 print(locals()) # 打印局部做⽤域中的內容 func()
global 使用示例
1 a = 100 2 def func(): 3 global a # 加了個global表示再也不局部建立這個變量了. 而是直接使用全局的a 4 a = 28 5 print(a) 6 func() 7 print(a)
nonlocal 使用示例
1 a = 10 2 def func1(): 3 a = 20 4 def func2(): 5 nonlocal a 6 a = 30 7 print(a) 8 func2() 9 print(a) 10 func1()
1.函數名能夠賦值給其餘變量
2.函數名能夠當作函數的參數
3.函數名能夠做爲函數的返回值
4.函數名能夠做爲list元素
賦值:
1 def func(): 2 print("呵呵") 3 print(func) 4 a = func # 把函數當成⼀個變量賦值給另⼀個變量 5 a() # 函數調⽤ func()
作list元素:
1 def func1(): 2 print("呵呵") 3 def func2(): 4 print("呵呵") 5 def func3(): 6 print("呵呵") 7 def func4(): 8 print("呵呵") 9 lst = [func1, func2, func3,func4] 10 for i in lst: 11 i()
作返回值:
1 def func_1(): 2 print("這裏是函數1") 3 def func_2(): 4 print("這裏是函數2") 5 print("這裏是函數1") 6 return func_2 7 fn = func_1() # 執行函數1. 函數1返回的是函數2, 這時fn指向的就是上面函數2 8 fn() # 執行上面返回的函數
閉包就是內層函數, 對外層函數(非全局)的變量的引用. 叫閉包
1 def func1(): 2 name = "alex" 3 def func2(): 4 print(name) # 閉包 5 func2() 6 func1()
咱們可使用__closure__來檢測函數是不是閉包. 使用函數名.__closure__返回cell就是 閉包. 返回None就不是閉包
1 def func1(): 2 name = "alex" 3 def func2(): 4 print(name) # 閉包 5 func2() 6 print(func2.__closure__) # (<cell at 0x10c2e20a8: str object at0x10c3fc650>,) 7 func1()
閉包的特徵:
常駐內存
安全
可迭代對象:str ,list,dict,tuple,set,range iterable(可迭代對象) 內部包含 __iter__() 函數
迭代器:文件句柄 iterator(迭代器) 內部包含__iter__() 和 __next__() 函數
迭代器示例:
1 lst = ['假','裝','我','是','迭','代','器'] 2 3 f = lst.__iter__() 4 while 1: 5 try: 6 name = f.__next__() 7 print(name) 8 except StopIteration: 9 break
獲取生成器函數 __next__():
1 def func(): 2 print('僞裝我是一個功能') 3 yield '然而並非' 4 print('僞裝我是小蝌蚪') 5 yield '你看不見我' 6 print('僞裝我是一陣風') 7 yield '無影無形' 8 9 s = func() 10 print(s.__next__()) 11 print(s.__next__()) 12 print(s.__next__())
節省內存的方法:
1 def eggs(): 2 i = 1 3 while i < 101: 4 yield '雞蛋%s' % i 5 i += 1 6 s = eggs() 7 print(s.__next__()) 8 print(s.__next__()) 9 print(s.__next__()) 10 print(s.__next__())
獲取生成器函數 send():
1 def eat(): 2 print("我吃什麼啊") 3 a = yield "饅頭" 4 print("a=",a) 5 b = yield "⼤餅" 6 print("b=",b) 7 c = yield "⾲菜盒⼦" 8 print("c=",c) 9 yield "GAME OVER" 10 gen = eat() # 獲取⽣成器 11 ret1 = gen.__next__() 12 print(ret1) 13 ret2 = gen.send("胡辣湯") 14 print(ret2) 15 ret3 = gen.send("狗糧") 16 print(ret3) 17 ret4 = gen.send("貓糧") 18 print(ret4)
列表推導式:
[結果 for 變量 in 可迭代對象 if 條件]
1 # 獲取1-100內能被3整除的數 2 lst = [i for i in range(1,101) if i % 3 == 0] 3 print(lst)
1 # 尋找名字中帶有兩個e的人的名字 2 names = [['Tom', 'Billy', 'Jefferson' , 'Andrew' , 'Wesley' , 'Steven' ,'Joe'],['Alice', 'Jill' , 'Ana', 'Wendy', 'Jennifer', 'Sherry' , 'Eva']] 3 lst = [a for i in names for a in i if a.count('e') == 2] 4 print(lst)
字典推導式:
{結果 for 變量 in 可迭代對象 if 條件} 結果是鍵值對=》key:value
1 # 字典推導式 2 3 list1 = ['假', '裝', '我', '是', '一', '陣', '風'] 4 list2 = ['你','看','我','是','6','個', '字'] 5 6 dic = {list1[i]:list2[i] for i in range(len(list1))} 7 print(dic)
集合推導式:
{結果 for 變量 in 可迭代對象 if 條件} 結果是 key
1 lst = [1, -1, 8, -8, 12] 2 # 絕對值去重 3 s = {abs(i) for i in lst} 4 print(s)
生成器表達式和列表推導式的區別:
1.列表推導式比較耗內存. 一次性加載. 生成器表達式幾乎不佔用內存. 使用的時候才分 配和使用內存
2.獲得的值不同. 列表推導式獲得的是一個列表. 生成器表達式獲取的是一個生成器