❶ python什麼是閉包 閉包的作用域
簡單說,閉包就是根據不同的配置信息得到不同的結果
再來看看專業的解釋:閉包(Closure)是詞法閉包(Lexical
Closure)的簡稱,是引用了自由變數的函數。這個被引用的自由變數將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法
認為閉包是由函數和與其相關的引用環境組合而成的實體。
python實例
看概念總是讓人摸不著頭腦,看幾個python小例子就會了
def make_adder(addend):
def adder(augend):
return augend + addend
return adder
p = make_adder(23)
q = make_adder(44)
print p(100)
print q(100)
運行結果:
123
144
分析一下:
我們發現,make_adder是一個函數,包括一個參數addend,比較特殊的地方是這個函數裡面又定義了一個新函數,這個新函數裡面的一個變數正好是外部make_adder的參數.也就是說,外部傳遞過來的addend參數已經和adder函數綁定到一起了,形成了一個新函數,我們可以把addend看做新函數的一個配置信息,配置信息不同,函數的功能就不一樣了,也就是能得到定製之後的函數.
再看看運行結果,我們發現,雖然p和q都是make_adder生成的,但是因為配置參數不同,後面再執行相同參數的函數後得到了不同的結果.這就是閉包.
❷ python閉包問題
這里的a就是fun2,用括弧call所以就運行fun2
同理fun1()()不但運行fun1也運行fun2
❸ python函數的閉包怎麼理解
1. 閉包的概念
首先還得從基本概念說起,什麼是閉包呢?來看下維基上的解釋:
復制代碼代碼如下:
在計算機科學中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變數的函數。這個被引用的自由變數將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。閉包在運行時可以有多個實例,不同的引用環境和相同的函數組合可以產生不同的實例。
....
上面提到了兩個關鍵的地方: 自由變數 和 函數, 這兩個關鍵稍後再說。還是得在贅述下「閉包」的意思,望文知意,可以形象的把它理解為一個封閉的包裹,這個包裹就是一個函數,當然還有函數內部對應的邏輯,包裹裡面的東西就是自由變數,自由變數可以在隨著包裹到處游盪。當然還得有個前提,這個包裹是被創建出來的。
在通過Python的語言介紹一下,一個閉包就是你調用了一個函數A,這個函數A返回了一個函數B給你。這個返回的函數B就叫做閉包。你在調用函數A的時候傳遞的參數就是自由變數。
舉個例子:
復制代碼代碼如下:
def func(name):
def inner_func(age):
print 'name:', name, 'age:', age
return inner_func
bb = func('the5fire')
bb(26) # >>> name: the5fire age: 26
這裡面調用func的時候就產生了一個閉包——inner_func,並且該閉包持有自由變數——name,因此這也意味著,當函數func的生命周期結束之後,name這個變數依然存在,因為它被閉包引用了,所以不會被回收。
另外再說一點,閉包並不是Python中特有的概念,所有把函數做為一等公民的語言均有閉包的概念。不過像java這樣以class為一等公民的語言中也可以使用閉包,只是它得用類或介面來實現。
更多概念上的東西可以參考最後的參考鏈接。
2. 為什麼使用閉包
基於上面的介紹,不知道讀者有沒有感覺這個東西和類有點相似,相似點在於他們都提供了對數據的封裝。不同的是閉包本身就是個方法。和類一樣,我們在編程時經常會把通用的東西抽象成類,(當然,還有對現實世界——業務的建模),以復用通用的功能。閉包也是一樣,當我們需要函數粒度的抽象時,閉包就是一個很好的選擇。
在這點上閉包可以被理解為一個只讀的對象,你可以給他傳遞一個屬性,但它只能提供給你一個執行的介面。因此在程序中我們經常需要這樣的一個函數對象——閉包,來幫我們完成一個通用的功能,比如後面會提到的——裝飾器。
3. 使用閉包
第一種場景 ,在python中很重要也很常見的一個使用場景就是裝飾器,Python為裝飾器提供了一個很友好的「語法糖」——@,讓我們可以很方便的使用裝飾器,裝飾的原理不做過多闡述,簡言之你在一個函數func上加上@decorator_func, 就相當於decorator_func(func):
復制代碼代碼如下:
def decorator_func(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@decorator_func
def func(name):
print 'my name is', name
# 等價於
decorator_func(func)
在裝飾器的這個例子中,閉包(wrapper)持有了外部的func這個參數,並且能夠接受外部傳過來的參數,接受過來的參數在原封不動的傳給func,並返回執行結果。
這是個簡單的例子,稍微復雜點可以有多個閉包,比如經常使用的那個LRUCache的裝飾器,裝飾器上可以接受參數@lru_cache(expire=500)這樣。實現起來就是兩個閉包的嵌套:
復制代碼代碼如下:
def lru_cache(expire=5):
# 默認5s超時
def func_wrapper(func):
def inner(*args, **kwargs):
# cache 處理 bala bala bala
return func(*args, **kwargs)
return inner
return func_wrapper
@lru_cache(expire=10*60)
def get(request, pk)
# 省略具體代碼
return response()
不太懂閉包的同學一定得能夠理解上述代碼,這是我們之前面試經常會問到的面試題。
第二個場景 ,就是基於閉包的一個特性——「惰性求值」。這個應用比較常見的是在資料庫訪問的時候,比如說:
復制代碼代碼如下:
# 偽代碼示意
class QuerySet(object):
def __init__(self, sql):
self.sql = sql
self.db = Mysql.connect().corsor() # 偽代碼
def __call__(self):
return db.execute(self.sql)
def query(sql):
return QuerySet(sql)
result = query("select name from user_app")
if time > now:
print result # 這時才執行資料庫訪問
上面這個不太恰當的例子展示了通過閉包完成惰性求值的功能,但是上面query返回的結果並不是函數,而是具有函數功能的類。有興趣的可以去看看Django的queryset的實現,原理類似。
第三種場景 , 需要對某個函數的參數提前賦值的情況,當然在Python中已經有了很好的解決訪問 functools.parial,但是用閉包也能實現。
復制代碼代碼如下:
def partial(**outer_kwargs):
def wrapper(func):
def inner(*args, **kwargs):
for k, v in outer_kwargs.items():
kwargs[k] = v
return func(*args, **kwargs)
return inner
return wrapper
@partial(age=15)
def say(name=None, age=None):
print name, age
say(name="the5fire")
# 當然用functools比這個簡單多了
# 只需要: functools.partial(say, age=15)(name='the5fire')
看起來這又是一個牽強的例子,不過也算是實踐了閉包的應用。
❹ 什麼是Python中的閉包
閉包
1.函數引用
運行結果:
圖解:
相關推薦:《Python視頻教程》
2.什麼是閉包
運行結果:
3.看一個閉包的實際例子:
運行結果:
這個例子中,函數line與變數a,b構成閉包。在創建閉包的時候,我們通過line_conf的參數a,b說明了這兩個變數的取值,這樣,我們就確定了函數的最終形式(y = x + 1和y = 4x + 5)。我們只需要變換參數a,b,就可以獲得不同的直線表達函數。由此,我們可以看到,閉包也具有提高代碼可復用性的作用。
如果沒有閉包,我們需要每次創建直線函數的時候同時說明a,b,x。這樣,我們就需要更多的參數傳遞,也減少了代碼的可移植性。
相關推薦:
Python中的迭代器是什麼
❺ python閉包問題求解!
a = fun1(),是調用f1, 所以a是函數fun2
多次調用f1()(),每次x都重置.
但是多次調用f2, 沒有重置所以會變化
deffun1():
x=5
deffun2():
nonlocalx
x+=1
returnx
returnfun2
print(fun1()())
print(fun1()())
print()
a=fun1()
print(a())
print(a())
print()
b=fun1
print(b()())
print(b()())
print()
6
6
6
7
6
6
❻ python閉包問題求解
因為python具有late binding的機制——閉包中內部函數的值只有在被調用時才會確定,等到f1,f2,f3調用時,此時閉包中f()函數的i已經等於3了,於是所有結果等於9.
如果想得到你要的結果,就得提前把i作為參數傳入,把原先的def f():所在行修改為def f(i=i)即可,其中等號左邊的i是形參,等號右邊的i是for in 循環中對應的i
defcount():
fs=[]
foriinrange(1,4):
deff(i=i):
returni**2
fs.append(f)
returnfs
f1,f2,f3=count()
print(f1())
print(f2())
print(f3())
輸出
1
4
9
❼ Python中什麼是閉包
閉包就是能夠讀取其他函數內部變數的函數。例如在javascript中,只有函數內部的子函數才能讀取局部變數,所以閉包可以理解成「定義在一個函數內部的函數「。在本質上,閉包是將函數內部和函數外部連接起來的橋梁。
閉包包含自由(未綁定到特定對象)變數,這些變數不是在這個代碼塊內或者任何全局上下文中定義的,而是在定義代碼塊的環境中定義(局部變數)。「閉包」 一詞來源於以下兩者的結合:要執行的代碼塊(由於自由變數被包含在代碼塊中,這些自由變數以及它們引用的對象沒有被釋放)和為自由變數提供綁定的計算環境(作用域)。在PHP、Scala、Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等語言中都能找到對閉包不同程度的支持。
❽ python閉包有什麼用
閉包於我而言即是函數式編程. python 作者之一 k 神大名鼎鼎的 fn.py.
❾ python閉包如何理解
首先會在g函數裡面找j,如果找不到,則會在外面一層找。如果在g函數裡面加一句j=4,則屏蔽了外面的j,會輸出三個16。另外,python3裡面可以運行
❿ python閉包問題
defcount():
fs=[]
foriinrange(1,4):
deff(j):
defg():
returnj*j
returng
fs.append(f(i))
#fs=[f(1),f(2),f(3)]=[]
returnfs
f1,f2,f3=count()
#f1,f2,f3=[f(1),f(2),f(3)]
printf1()
printf2()
printf3()
defhellocounter(name):
count=[0]
defcounter():
count[0]+=1
print'Hello,',name,',',str(count[0])+'access!'
returncounter
hello=hellocounter('ma6174')
hello()
hello()
hello()
具體的注釋在代碼里,第一不是閉包的使用方式,第二個是一個合理的閉包使用例子。
如果解決了您的問題請採納!
如果未解決請繼續追問