2017-09-07 15 views
8

Mô-đun giữ một từ điển để theo dõi ngữ cảnh của nó, chẳng hạn như các tên được xác định tại một số thời điểm thực hiện. Từ điển này có thể được truy cập thông qua vars(module) (hoặc module.__dict__) nếu module được nhập khẩu, hoặc bằng một cuộc gọi đến locals tích hợp chức năng trong module chính nó:Khi nào bộ từ điển cục bộ được đặt?

Cập nhật và gửi lại một cuốn từ điển đại diện cho bảng ký hiệu cục bộ hiện hành.

Nhưng tôi thấy mình bối rối, khi tôi thử truy cập từ điển người dân địa phương từ một hàm. Kết quả của một kịch bản chỉ chứa sau đây là một từ điển rỗng:

def list_locals(): 
    print(locals()) 

list_locals() 

Nhưng mặt khác, nếu một kịch bản có chứa độc quyền sau đây, đầu ra là từ điển mong đợi, chứa __name__, __doc__ và các mô-đun khác biến -level:

print(locals()) 

Vì vậy, khi nào nội dung của từ điển địa phương được đặt? Ngoài ra, "cập nhật" có nghĩa là gì trong định nghĩa của hàm locals?

+0

Ở cấp mô-đun, hãy thử 'in (địa phương() là globals())' –

+0

@Chris_Rands Yep, đó là một phần của sự nhầm lẫn của tôi. –

Trả lời

7

Không gian tên của một module là toàn cầu namespace, truy cập thông qua globals(). Không có không gian tên cục bộ riêng biệt, do đó, locals(), bên ngoài các hàm, chỉ trả về không gian tên chung.

Chỉ các hàm có vùng tên cục bộ. Lưu ý rằng locals() là sự phản ánh một chiều của không gian tên đó; việc triển khai CPython cho các chức năng được tối ưu hóa cao và bạn không thể thêm hoặc thay đổi các biến cục bộ thông qua từ điển locals(). Từ điển được trả về bởi locals() được cập nhật bất cứ khi nào không gian tên đã thay đổi giữa các cuộc gọi đến hàm đó.

Cũng lưu ý rằng những thứ như danh sách/dict/set comprehensions, biểu thức máy phát và các lớp trong thực tế cũng được thực hiện như các hàm, mặc dù với các quy tắc không gian tên khác nhau. Trong các ngữ cảnh như vậy locals() cũng sẽ trả về không gian tên cục bộ của hàm riêng biệt.

+1

Như thường lệ, sự đồng thuận và rõ ràng, cảm ơn! –

1

Nếu bạn gọi locals() nhiều lần trong cùng một cuộc gọi chức năng, nó sẽ trả lại cùng một từ điển.

>>> def f(): 
...  d = locals() 
...  assert 'd' not in d 
...  locals() 
...  assert 'd' in d 
...  assert d is locals() 
...  print(d) 
... 
>>> f() 
{'d': {...}} 

"Update" trong trường hợp này có nghĩa là nội dung của từ điển này được cập nhật để phản ánh phạm vi hiện tại của các biến địa phương mà tồn tại, nhưng nếu bạn giữ một tham chiếu vào từ điển này thì từ điển sẽ vẫn được sử dụng.

Cũng lưu ý rằng từ điển địa phương không chứa khóa cho 'f', mặc dù bạn có thể đã truy cập khóa đó trong quá trình thực hiện chức năng. Trong trường hợp nó không rõ ràng, đó là một toàn cầu, không phải là một địa phương.

+0

Cảm ơn lời giải thích đó về ý nghĩa của "cập nhật". Mặc dù tôi rõ ràng đã trộn lẫn 'local' và 'globals', nhưng tôi muốn nói rằng tài liệu này phần nào lảng tránh về hành vi đó. Cảm ơn một lần nữa để làm rõ. –

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