Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Closure trong Python?


Để hiểu rõ closure trong Python, trước tiên hiểu hàm lồng (nested function) và class Python. Tóm lại, closure cũng là một hàm đóng gói dữ liệu với code.

Hàm lồng (Nested function) trong Python

Hàm được định nghĩa bên trong hàm khác gọi là hàm lồng. Hàm lồng có thể truy cập biến của phạm vi bao quanh (enclosing scope).

def funcOut():    print("This is outer function.")    def funcIn():       print("This function is defined inside funcOut. \nThis function(funcIn) is called\ nested function.")    print("We can call nested function here.")    funcIn() print("We are in outer function.\nCalling funcOut.") funcOut()

Kết quả

We are in outer function. Calling funcOut. This is outer function. We can call nested function here. This function is defined inside funcOut. This function(funcIn) is called nested function.

Vậy funcIn là hàm lồng được định nghĩa trong funcOut. Từ kết quả, hiểu được trình tự gọi hàm.

Nếu muốn có tất cả chức năng của funcIn từ funcOut, ta phải làm "return funcIn" trong chương trình trên, đây gọi là closure trong Python.

Tóm lại, closure là một hàm (đối tượng) nhớ môi trường tạo ra nó (phạm vi bao quanh).

def closureFunc(start):    def incrementBy(inc):       return start + inc    return incrementBy closure1 = closureFunc(9) closure2 = closureFunc(90) print ('clsure1(3) = %s' %(closure1(3))) print ('closure2(3) = %s' %(closure2(3)))

Kết quả

clsure1(3) = 12 closure2(3) = 93

Gọi biến closure1 (kiểu function) với closure1(3) trả về 12, trong khi closure2(3) trả về 93. Mặc dù closure1 và closure2 đều tham chiếu cùng hàm incrementBy, ta có hai biến closure1 & closure2 khác nhau bị ràng buộc (bind) bởi identifier closureFunc, dẫn đến kết quả khác nhau.

Thuộc tính __closure__ và cell objects

Để lấy thêm thông tin, dùng thuộc tính __closure__ và cell objects:

def closureFunc(start):    def incrementBy(inc):       return start + inc    return incrementBy a= closureFunc(9) b = closureFunc(90) print ('type(a)=%s' %(type(a))) print ('a.__closure__=%s' %(a.__closure__)) print ('type(a.__closure__[0])=%s' %(type(a.__closure__[0]))) print ('a.__closure__[0].cell_contents=%s' %(a.__closure__[0].cell_contents)) print ('type(b)=%s' %(type(b))) print ('b.__closure__=%s' %(b.__closure__)) print ('type(b.__closure__[0])=%s' %(type(b.__closure__[0]))) print ('b.__closure__[0].cell_contents=%s' %(b.__closure__[0].cell_contents))

Kết quả

type(a) = <class 'function'> a.__closure__ = <cell at 0x057F8490: int object at 0x68A65770> type(a.__closure__[0]) = <class 'cell'> a.__closure__[0].cell_contents = 9 type(b)=<class 'function'> b.__closure__ = <cell at 0x0580BD50: int object at 0x68A65C80> type(b.__closure__[0]) = <class 'cell'> b.__closure__[0].cell_contents=90

Từ kết quả trên, thấy mỗi cell của object giữ giá trị tại thời điểm tạo nó.