Trong Python, một bao đóng là một ví dụ của một hàm có các biến liên kết với nó là bất biến.
Trên thực tế, mô hình dữ liệu giải thích điều này trong phần mô tả __closure__
thuộc tính của các hàm :
Không có hoặc nhiều ô chứa liên kết cho các biến tự do của hàm. Chỉ đọc
Để chứng minh điều này:
def enclosure(foo):
def closure(bar):
print(foo, bar)
return closure
closure_instance = enclosure('foo')
Rõ ràng, chúng ta biết rằng bây giờ chúng ta có một hàm được trỏ đến từ tên biến closure_instance
. Rõ ràng, nếu chúng ta gọi nó bằng một đối tượng, bar
thì nó sẽ in ra chuỗi 'foo'
và bất kể biểu thức chuỗi bar
là gì.
Trên thực tế, chuỗi 'foo' được liên kết với phiên bản của hàm và chúng ta có thể đọc trực tiếp nó tại đây, bằng cách truy cập cell_contents
thuộc tính của ô đầu tiên (và duy nhất) trong bộ của __closure__
thuộc tính:
>>> closure_instance.__closure__[0].cell_contents
'foo'
Ngoài ra, các đối tượng ô được mô tả trong tài liệu API C:
Đối tượng "ô" được sử dụng để triển khai các biến được tham chiếu bởi nhiều phạm vi
Và chúng tôi có thể chứng minh cách sử dụng của hàm đóng, lưu ý rằng 'foo'
nó bị mắc kẹt trong hàm và không thay đổi:
>>> closure_instance('bar')
foo bar
>>> closure_instance('baz')
foo baz
>>> closure_instance('quux')
foo quux
Và không gì có thể thay đổi nó:
>>> closure_instance.__closure__ = None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: readonly attribute
Chức năng một phần
Ví dụ được đưa ra sử dụng hàm đóng làm một phần, nhưng nếu đây là mục tiêu duy nhất của chúng ta, thì mục tiêu tương tự có thể được thực hiện với functools.partial
>>> from __future__ import print_function
>>> partial_function = functools.partial(print, 'foo')
>>> partial_function('bar')
foo bar
>>> partial_function('baz')
foo baz
>>> partial_function('quux')
foo quux
Có nhiều cách đóng phức tạp hơn sẽ không phù hợp với ví dụ hàm một phần và tôi sẽ trình bày thêm khi thời gian cho phép.
nonlocal
đã được bổ sung trong python 3, python 2.x không có đầy đủ-on, read-write đóng cửa (tức là bạn có thể đọc đóng qua các biến, nhưng không thay đổi giá trị của họ)