Trong Python, cell
đối tượng được sử dụng để lưu trữ free variables của một closure.
Giả sử bạn muốn hàm luôn trả về một phần cụ thể của đối số của nó. Bạn có thể sử dụng một đóng cửa để đạt được điều này:
def multiplier(n, d):
"""Return a function that multiplies its argument by n/d."""
def multiply(x):
"""Multiply x by n/d."""
return x * n/d
return multiply
Và đây là cách bạn có thể sử dụng nó:
>>> two_thirds = multiplier(2, 3)
>>> two_thirds(7)
4.666666666666667
như thế nào two_thirds
nhớ các giá trị của n
và d
? Chúng không phải là đối số của hàm multiply
được xác định, chúng không phải là biến cục bộ được xác định bên trong multiply
, chúng không phải là hình cầu, và vì multiplier
đã chấm dứt, các biến cục bộ của nó không còn tồn tại nữa, đúng không?
Điều gì xảy ra khi multiplier
được biên dịch, phiên dịch thông báo rằng multiply
sẽ muốn sử dụng các biến địa phương sau, vì vậy nó giữ một lưu ý trong số họ:
>>> multiplier.__code__.co_cellvars
('d', 'n')
Sau đó, khi multiplier
được gọi, giá trị của các biến cục bộ bên ngoài được lưu trữ trong thuộc tính chức năng quay trở lại của __closure__
, như một tuple của cell
đối tượng:
>>> two_thirds.__closure__
(<cell at 0x7f7a81282678: int object at 0x88ef60>,
<cell at 0x7f7a81282738: int object at 0x88ef40>)
... với tên của họ trong __code__
đối tượng như co_freevars
:
>>> two_thirds.__code__.co_freevars
('d', 'n')
Bạn có thể có được ở các nội dung của các tế bào sử dụng cell_contents
thuộc tính của họ:
>>> {v: c.cell_contents for v, c in zip(
two_thirds.__code__.co_freevars,
two_thirds.__closure__
)}
{'d': 3, 'n': 2}
Bạn có thể đọc thêm về việc đóng cửa và việc thực hiện trong Tờ trình Python Enhancement mà giới thiệu chúng: PEP 227 — Statically Nested Scopes.
Trong Rust, 'Cell' chỉ là một cách để di chuyển xung quanh tính bất biến để bạn có thể sửa đổi dữ liệu mặc dù có tham chiếu không thay đổi được. Đây là một điều hoàn toàn khác với ý nghĩa của Python. "Cell" là một thuật ngữ khá chung chung, bạn biết đấy. –
@ChrisMorgan có vẻ như bạn đã quen với Cell trong cả hai ngữ cảnh mà tôi đề cập đến. Bạn có sẵn lòng gửi câu trả lời không? –
Tôi không thực sự quen thuộc với nội bộ của biểu diễn đối tượng mã Python, nhưng tôi có thể đoán được ý nghĩa của từ "ô". –