def f1(): x = 1 def inner(): print(x) return inner func = f1() x = 2 def f2(): x = 3 func() f2()
1
一丶什麼是閉包
閉包:閉是封閉(函數內部函數),包是包含(該內部函數對外部做用域而非全局做用域的變量的引用)。閉包指的是:函數內部函數對外部做用域而非全局做用域的引用。
提示:以前咱們都是經過參數將外部的值傳給函數,閉包提供了另一種思路,包起來嘍,包起呦,包起來哇。python
def outter(): x = 1 def inner(): print(x) return inner f = outter() def f2(): x = 2 f() f2()
1.1 兩種爲函數傳參的方式閉包
爲函數傳參的方式一:使用參數的形式 def func(x): print(x) func(1) func(1) func(1)
1 1 1
函數
爲函數傳參的方式二:包給函數url
def outter(x): x = 1 def inner(): print(x) return inner f = outter(1) f() f() f() # 查看閉包的元素 print(F"f.__closure__[0].cell_contents: {f.__closure__[0].cell_contents}")
1 1 1 f.__closure__[0].cell_contents: 1
code
閉包的意義:返回的函數對象,不單單是一個函數對象,在該函數外還包裹了一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域。對象
應用領域:延遲計算(原來咱們是傳參,如今咱們是包起來)、爬蟲領域。
不用閉包的繁瑣代碼:blog
import requests def get(url): response = requests.get(url) print(f"done: {url}") get('https://www.baidu.com') get('https://www.baidu.com') get('https://www.baidu.com') get('https://www.cnblogs.com/linhaifeng') get('https://www.cnblogs.com/linhaifeng') get('https://www.cnblogs.com/linhaifeng')
done: https://www.baidu.com done: https://www.baidu.com done: https://www.baidu.com done: https://www.cnblogs.com/linhaifeng done: https://www.cnblogs.com/linhaifeng done: https://www.cnblogs.com/linhaifeng
上面的方式是極其複雜的,咱們若是使用默認參數也只能解決一個網址,所以咱們能夠考慮使用閉包的方式。作用域
import requests def outter(url): def get(): response = requests.get(url) print(f"done: {url}") return get baidu=outter('https://www.baidu.com') python = outter('https://www.python.org') baidu() baidu() python() python()
done: https://www.baidu.com done: https://www.baidu.com done: https://www.python.org done: https://www.python.org
get