8-函式高階
阿新 • • 發佈:2020-11-19
函式高階使用
-
f:既是函式名稱,也是指向函式的一個變數
-
所有指向函式的變數都可以呼叫該函式
-
回撥函式
- m1(3, m2)
- m1是普通函式,m2作為引數,在m1內部呼叫m2
函式作用域
- 作用域:起作用的範圍
- 區域性變數與全域性變數
- 區域性變數:函式內部定義的變數,只能在函式內部使用
- nonlocal b
- 呼叫非本地(函式內部)的最近的b
- 優點:不會被外部干擾
- 缺點:記憶體會被回收(變數會被刪除)
- 全域性變數:函式外部定義的變數,具有全域性作用域
- 預設不可以修改全域性變數
- global 作用是a使用的是全域性變數a
- global a
- 優點:記憶體不會被回收(變數不會被刪除)
- 缺點:可能會被幹擾
- 區域性變數:函式內部定義的變數,只能在函式內部使用
函式巢狀和閉包
-
函式巢狀
-
def f1(): print('f1') def f2(): print('f2') # f2() return f2 res = f1() # res = f2 res() # 等價於f2()
-
傳參
- f(3)(4)
-
-
函式閉包
-
閉包:函式巢狀,把內部函式返回,可以讓外部函式中的引數或變數不被釋放(讓變數不消失)
-
閉包的特點:不會被外部干擾,記憶體也不會被回收
-
def out(): p = 10 def inner(): nonlocal p p += 1 print('p=', p) return inner f = out() # f = inner f() # 11,相當於inner() f() # 12 f() # 13
-
-
生成器擴充套件
- 生成器和迭代器很相似,其實它們都是消費者和生產者模型,都是使用者通過next()方法來獲得資料,而生成器和迭代器都是隻有使用者在呼叫next()時才返回資料。不同的是迭代器是通過自己實現next()方法來逐步返回資料,而生成器則使用yield自動完成了提供資料並且讓程式進入wait狀態,等待使用者的進一步操作,所以生成器更加靈活和方便
- 生成器的方法
- next()方法
- send(msg)方法
- 當使用send(msg)傳送訊息給生成器時,wait_and_get會檢測到這個資訊,然後喚醒生成器,同時該方法獲取msg並賦值給x
- g.send(5)
- throw()方法
- 生成器提供throw()方法從生成器內部來引發異常,從而控制生成器的執行
- h.throw(GeneratorExit)
- close()方法
- 當使用close()方法時,生成器會直接從當前狀態退出
- 生成器的用途
- 節省記憶體
- 線性遍歷訪問資料
- 生成器可以將非線性化的處理轉換成線性化的方式,典型的例子就是對二叉樹的訪問。傳統的方法是使用遞迴函式來訪問和處理,需要將處理方法放到訪問的過程中,既容易出錯也不清晰。比較好的方法是先將樹的節點訪問轉換成線性,然後在外面遍歷每一個節點,這樣一來,處理每個節點的過程不需要放到訪問每個節點的diamagnetic中去,更加清晰
列表生成器&列表生成式
-
列表生成式
- ages = [i * 10 for i in range(2, 5) if 2 < i < 4]
- l3 = [i+j for i in l1 for j in l2]
-
字典生成式
- d = {i: i+1 for i in range(1, 4)} # {1: 2, 2: 3, 3: 4}
-
列表生成器
-
ages = (i for i in range(5)) # <generator object <genexpr> at 0x0000015A66E54AC8>
-
生成器物件:可以不一次性佔用太多的記憶體空間,我們一般需要一個一個元素取出來
-
next函式
-
print(next(ages)) # 0 print(next(ages)) # 1 print(next(ages)) # 2
-
-
生成器函式
- 生成器函式:在普通函式中包含yield關鍵字,則是生成器函式
- yield:
- 1.寫在函式中,讓普通函式變成生成器函式
- 2.可以返回值,但是不會退出函式
- 3.需要結合next使用,每次使用next,則會執行至下一個yield
-
計算程式碼耗時
-
計算程式碼耗時
-
import time start = time.time() # 獲取當前時間 for i in range(1000): pass end = time.time() print(end - start)
-
可迭代物件&迭代器
-
from collections.abc import Iterable # 可迭代物件
-
from collections.abc import Iterator # 迭代器
-
可迭代物件
- 可迭代物件:只要可以使用for-in迴圈,就是可迭代物件
- 有:list, tuple, dict, set, str,generator
-
isinstance(): 檢測某個物件是否屬於某個類
- print(isinstance([1, 3], Iterable)) # True
-
迭代器
-
迭代器:既要能用for-in迴圈,且可以使用next呼叫
-
iter():將可迭代物件變成迭代器
-
l = [1, 3, 4] l2 = iter(l) print(l2) # <list_iterator object at 0x0000017DB5C4BE48> print(next(l2)) # 1 print(list(l2)) # [3, 4], 1已經被取出了
-
-
_iter_()將可迭代物件變成迭代器
-
l1 = [1, 3, 4] l1_iter = l1.__iter__() print(type(l1_iter)) # <class 'list_iterator'> for x in l1_iter: print(x)
-
-
偏函式
print(int('10'))
print(int('10', base=2)) # 2,將10看成是二進位制
print(int('1010', base=8)) # 520
import functools
int2 = functools.partial(int, base=2)
print(int2('1010')) # 10