aaronasterling ตอบคำถามนี้แล้ว
อย่างไรก็ตามบางคนอาจสนใจวิธีการจัดเก็บตัวแปรภายใต้ประทุน
ก่อนที่จะมาถึงตัวอย่าง:
การปิดคือฟังก์ชันที่รับค่าตัวแปรจากสภาพแวดล้อมที่ล้อมรอบ เมื่อคุณส่งการเรียกกลับฟังก์ชันเป็นอาร์กิวเมนต์ไปยังฟังก์ชันอื่นที่จะทำ I / O ฟังก์ชันการเรียกกลับนี้จะถูกเรียกใช้ในภายหลังและฟังก์ชั่นนี้จะเกือบน่าอัศจรรย์ - จำบริบทที่มีการประกาศพร้อมกับตัวแปรทั้งหมดที่มี ในบริบทนั้น
หากฟังก์ชั่นไม่ใช้ตัวแปรอิสระมันจะไม่ทำการปิด
หากมีอีกระดับภายในซึ่งใช้ตัวแปรอิสระ - ระดับก่อนหน้านี้ทั้งหมดบันทึกสภาพแวดล้อมคำ (ตัวอย่างในตอนท้าย)
แอตทริบิวต์ฟังก์ชั่นfunc_closure
ในหลาม <3.X หรือ__closure__
ในหลาม> 3.X บันทึกตัวแปรอิสระ
ทุกฟังก์ชั่นใน python มีคุณสมบัติการปิดนี้ แต่จะไม่บันทึกเนื้อหาใด ๆ หากไม่มีตัวแปรอิสระ
ตัวอย่าง: ของคุณลักษณะการปิด แต่ไม่มีเนื้อหาภายในเนื่องจากไม่มีตัวแปรอิสระ
>>> def foo():
... def fii():
... pass
... return fii
...
>>> f = foo()
>>> f.func_closure
>>> 'func_closure' in dir(f)
True
>>>
NB: ตัวแปรฟรีจะต้องสร้างการปิด
ฉันจะอธิบายโดยใช้ตัวอย่างข้อมูลเดียวกับด้านบน:
>>> def make_printer(msg):
... def printer():
... print msg
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer() #Output: Foo!
และฟังก์ชั่น Python ทั้งหมดมีคุณสมบัติการปิดดังนั้นเรามาตรวจสอบตัวแปรล้อมรอบที่เกี่ยวข้องกับฟังก์ชั่นการปิด
นี่คือคุณสมบัติfunc_closure
สำหรับฟังก์ชั่นprinter
>>> 'func_closure' in dir(printer)
True
>>> printer.func_closure
(<cell at 0x108154c90: str object at 0x108151de0>,)
>>>
closure
แอตทริบิวต์ส่งกลับ tuple ของวัตถุเซลล์ซึ่งมีรายละเอียดของตัวแปรที่กำหนดไว้ในขอบเขตล้อมรอบ
องค์ประกอบแรกใน func_closure ซึ่งอาจเป็น None หรือ tuple ของเซลล์ที่มีการเชื่อมสำหรับตัวแปรอิสระของฟังก์ชันและเป็นแบบอ่านอย่างเดียว
>>> dir(printer.func_closure[0])
['__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
>>>
ที่นี่ในผลลัพธ์ข้างต้นคุณสามารถดูcell_contents
ได้เรามาดูกันว่ามันเก็บอะไร:
>>> printer.func_closure[0].cell_contents
'Foo!'
>>> type(printer.func_closure[0].cell_contents)
<type 'str'>
>>>
ดังนั้นเมื่อเราเรียกว่าฟังก์ชั่นก็เข้าถึงค่าที่เก็บไว้ภายในprinter()
cell_contents
นี่คือวิธีที่เราได้รับผลลัพธ์เป็น 'Foo!'
ฉันจะอธิบายอีกครั้งโดยใช้ตัวอย่างด้านบนพร้อมการเปลี่ยนแปลงบางอย่าง:
>>> def make_printer(msg):
... def printer():
... pass
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer.func_closure
>>>
ในตัวอย่างด้านบนฉันไม่ได้พิมพ์ msg ภายในฟังก์ชันเครื่องพิมพ์ดังนั้นจึงไม่สร้างตัวแปรอิสระใด ๆ เนื่องจากไม่มีตัวแปรอิสระจึงไม่มีเนื้อหาภายในการปิด นั่นคือสิ่งที่เราเห็นด้านบน
ตอนนี้ฉันจะอธิบายตัวอย่างอื่นเพื่อล้างข้อมูลทุกอย่างFree Variable
ด้วยClosure
:
>>> def outer(x):
... def intermediate(y):
... free = 'free'
... def inner(z):
... return '%s %s %s %s' % (x, y, free, z)
... return inner
... return intermediate
...
>>> outer('I')('am')('variable')
'I am free variable'
>>>
>>> inter = outer('I')
>>> inter.func_closure
(<cell at 0x10c989130: str object at 0x10c831b98>,)
>>> inter.func_closure[0].cell_contents
'I'
>>> inn = inter('am')
ดังนั้นเราจะเห็นว่าfunc_closure
คุณสมบัติเป็น tuple ของเซลล์ปิดเราสามารถอ้างอิงได้และเนื้อหาของเซลล์เหล่านั้นอย่างชัดเจน - เซลล์มีคุณสมบัติ "cell_contents"
>>> inn.func_closure
(<cell at 0x10c9807c0: str object at 0x10c9b0990>,
<cell at 0x10c980f68: str object at 0x10c9eaf30>,
<cell at 0x10c989130: str object at 0x10c831b98>)
>>> for i in inn.func_closure:
... print i.cell_contents
...
free
am
I
>>>
ที่นี่เมื่อเราเรียกinn
มันจะอ้างอิงตัวแปรบันทึกฟรีทั้งหมดที่เราได้รับI am free variable
>>> inn('variable')
'I am free variable'
>>>