程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python knowledge: what is a closure?

編輯:Python

One 、Python Closure of (Closure)

         What is a closure ? Borrow here 《Fluent Python》 The definition of closure in "a closure is function with an extended scope that encompasses non-global variables referenced in the body of the function but not defined there". Simply speaking : Closure = function + Reference to free variables .

         So what are free variables (free variables)? In a function , If a variable is neither created inside the function nor is a formal parameter of the function , And it is not a global variable (global variables), Then this variable is a free variable for the function . If you say too much, you might as well give an example :

def outer():
var = 3
def inner():
print(var)
return inner
func = outer()
func() # print 3
var = 5
func() # print 3

         In this code , function inner and var It's a closure ,var about inner It's a free variable . You can see var Not in inner Created in the , But in outer Created in . So the function inner How to store variables var Well ? The answer is inner.__code__.co_freevars and inner.__closure__, The former records the name of the free variable , The latter records the value of the free variable .

print func.__code__.co_freevars # ('var',)
print func.__closure__[0].cell_contents # 3

  Two 、 Working mechanism

         Closure unit refers to the value required by the function , But from the surrounding area .

         When Python When compiling nested functions , It will note the parent functions that it references but only in the nested functions and code objects of the parent scope ( It's not a global variable ) Any variable defined in . These are, respectively, of these functions __code__ On the object co_freevars and co_cellvars attribute .

         then , When you actually create nested functions ( Occurs when the parent function is executed ) when , These references will be used to attach closures to nested functions .

         Function closure contains a unit tuple , Each cell corresponds to a free variable ( With co_freevars name ); A cell is a special reference to a local variable of the parent scope , It follows the values that those local variables point to . It is best to illustrate this with an example : 

def foo():
def bar():
print(spam)
spam = 'ham'
bar()
spam = 'eggs'
bar()
return bar
b = foo()
b()

         In the example above , function bar There is a closure unit , It points to a function foo Spam in . Cells follow spam values . what's more , once foo() Complete and return bar, Even if foo The variables in the spam No longer exist , The cell will continue to reference the value ( String egg ).

therefore , The above code output : 

>>> b=foo()
ham
eggs
>>> b()
eggs

here , b.__closure__[0].cell_contents yes  'eggs'

Please note that , call bar() Will dereference the closure ; Closures do not capture the value here . When you generate nested functions that reference circular variables ( Use lambda Expression or def sentence ) when , This will be different :

def foo():
bar = []
for spam in ('ham', 'eggs', 'salad'):
bar.append(lambda: spam)
return bar
for bar in foo():
print bar()

         Above he will print continuously 3 Secondary salad , Because all three lambda Functions refer to spam Variable , Instead of the value bound when the function object is created . When for At the end of the loop , Spam is bound to “ salad ”, So all three closures will resolve to this value .

>>>python.__closure__
(<cell at 0x67f50: str object at 0x69230>,)
>>>python.__closure__[0].cell_contents

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved