2014-05-20 18 views
5

Đối tượng mã Python có thuộc tính co_cellvars. Tài liệu về số PyPy's bytecode interpreter thường sử dụng thuật ngữ Ô số.Một ô trong ngữ cảnh của trình thông dịch hoặc trình biên dịch là gì?

Trong số các langauges khác, Rust provides a Cell datatype. Googling cho thấy họ liên quan đến việc đóng cửa bằng cách nào đó.

một tế bào là gì, trong bối cảnh của một ngôn ngữ lập trình thực hiện? Các tế bào giải quyết vấn đề gì?

+1

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. –

+0

@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? –

+0

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ừ "ô". –

Trả lời

9

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 nd? 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.

Các vấn đề liên quan