Mối quan hệ giữa phạm vi và không gian tên trong Python là gì?


12

Trong nhiều tài nguyên tôi thấy "phạm vi""không gian tên" được sử dụng thay thế cho nhau, điều này có vẻ hơi khó hiểu vì chúng có nghĩa là những thứ khác nhau.

  • Phạm vi xác định vùng mã nơi có sẵn tên.
  • Quy tắc LEGB xác định cách nhìn tên.
  • Không gian tên là một nơi mà bạn tìm kiếm tên.

Sau đó tôi đọc:

  • "Tên được liên kết với một không gian tên theo nơi chúng được gán ..." (mà tôi tin là thỏa thuận với phạm vi trong phạm vi từ vựng).
  • "Các chức năng thêm một lớp không gian tên bổ sung cho các chương trình của bạn" [ ref. ] (họ không thêm phạm vi địa phương bổ sung à?)
  • "tất cả các tên được gán bên trong một định nghĩa hàm được đặt trong phạm vi cục bộ (không gian tên được liên kết với lệnh gọi hàm)."
  • "phạm vi toàn cầu, đó là một không gian tên trong đó các biến được tạo (được gán) ở cấp cao nhất của tệp mô-đun trực tiếp."

* tất cả các trích dẫn là từ việc học python phiên bản 5 ch17

Các không gian tên trong Python có cách phạm vi được thực hiện không? Họ là những điều tương tự? Bất cứ ai có thể khai sáng cho tôi?


1
Bạn có thể cung cấp tài liệu tham khảo cho các trích dẫn - tôi có thể tìm thấy một, nhưng không phải cái khác.
jonrsharpe

1
Không gian tên chỉ là một loại phạm vi. Xem stackoverflow.com/questions/291978/ trộm
Robert Harvey

Câu trả lời:


16

Một không gian tên là một từ điển, ánh xạ tên (dưới dạng chuỗi) thành các giá trị. Khi bạn thực hiện một nhiệm vụ, như a = 1, bạn đang thay đổi một không gian tên. Khi bạn tạo một tham chiếu, như print(a), Python xem qua một danh sách các không gian tên để thử và tìm một cái có tên là một khóa.

Một phạm vi xác định không gian tên sẽ được xem xét và theo thứ tự nào. Phạm vi của bất kỳ tài liệu tham khảo luôn bắt đầu trong không gian tên địa phương, và di chuyển ra phía ngoài cho đến khi nó đạt đến namespace toàn cục của mô-đun, trước khi chuyển sang các builtins(không gian tên có chức năng tham khảo Python được xác định trước và hằng số, giống như rangegetattr), đó là sự kết thúc của dòng .

Hãy tưởng tượng bạn có một hàm được đặt tên inner, được lồng trong một hàm toàn cục có tên outerinnerchứa tham chiếu đến tên. Python đầu tiên nhìn vào innerkhông gian tên. Nếu tên không có, Python sẽ tìm trong outerkhông gian tên. Nếu thất bại, Python thử globalkhông gian tên của mô-đun , sau đó là builtinkhông gian tên, cuối cùng sẽ ném NameErrornếu tên không được tìm thấy.

Khi chúng ta nói xlà trong không gian tên của hàm, chúng ta có nghĩa là nó được định nghĩa ở đó, cục bộ trong hàm. Khi chúng ta nói xlà trong phạm vi của hàm, chúng ta có nghĩa xlà trong không gian tên của hàm hoặc trong bất kỳ không gian tên bên ngoài nào mà không gian tên của hàm được lồng bên trong.

Bất cứ khi nào bạn xác định một chức năng, bạn tạo một không gian tên mới và một phạm vi mới. Không gian tên là hàm băm mới, cục bộ của tên. Phạm vi là chuỗi không gian tên ngụ ý bắt đầu từ không gian tên mới, sau đó hoạt động theo cách thông qua bất kỳ không gian tên bên ngoài (phạm vi bên ngoài), cho đến không gian tên toàn cầu (phạm vi toàn cầu) và trên các nội trang.

Các thuật ngữ có thể được sử dụng gần như thay thế cho nhau, nhưng đó không phải vì chúng có nghĩa giống nhau; đó là bởi vì họ trùng lặp rất nhiều trong những gì họ ngụ ý.


3
"Các thuật ngữ có thể được sử dụng gần như thay thế cho nhau, nhưng đó không phải vì chúng có nghĩa giống nhau; đó là vì chúng trùng lặp rất nhiều trong những gì chúng ngụ ý."
Nikos

2
Câu trả lời này đúng về tinh thần, nhưng sai về chi tiết. Các lớp trong Python không giới thiệu một không gian tên mới, đó là lý do tại sao các thuộc tính lớp phải đủ điều kiện với tên lớp và tại sao các thuộc tính thể hiện phải đủ điều kiện với tên thể hiện. Các mức của không gian tên trong Python từ bên trong đến bên ngoài là Local, Enclifying, Global và Tích hợp. Một lớp có thể được định nghĩa ở bất kỳ cấp độ nào trong số này, nhưng các thành viên của một lớp phải luôn có đủ điều kiện.
Rob Smallshire

Bạn đúng. Các lớp học không hoạt động như tôi đã nói. Tôi đã nghĩ rằng họ tạo ra một phạm vi từ vựng giống như một chức năng, nhưng họ thì không. Vui lòng cập nhật câu trả lời nếu bạn có thời gian, nếu không tôi sẽ làm điều đó vào một lúc nào đó. Cảm ơn.
Carl Smith

1
+1 Câu trả lời xuất sắc, gói gọn sự tinh tế như vậy về mặt kinh tế. Tôi thấy điều này rất hữu ích, cảm ơn bạn!
người tìm kiếm

1
"Không gian tên là hàm băm của tên, cặp giá trị, rất giống từ điển Python" - Tôi khá chắc chắn rằng không gian tên được lưu trữ dưới dạng từ điển python. Chẳng hạn, bạn có thể chỉnh sửa không gian tên toàn cầu bằng cách gọi globalals (), cho phép bạn sửa đổi từ điển trực tiếp để liên kết các đối tượng và tên: ví dụ: globalals () [name] = "object". Câu trả lời tuyệt vời khác.
Evan Rosica

4

Có một bài viết tuyệt vời về không gian tên Python ở đây . Để trích dẫn phần có liên quan để trả lời câu hỏi của bạn về tham chiếu giữa phạm vi và không gian tên:

Một phạm vi đề cập đến một khu vực của một chương trình mà từ đó một không gian tên có thể được truy cập mà không có tiền tố.

Ví dụ, hãy tưởng tượng một chương trình lăn đơn giản:

import random  # 'random' is in module namespace

def roll(sides=6):  # 'roll' is in module namespace, 'sides' is in roll's
    return random.randint(1, sides)  # both 'random' and 'sides' are in scope here

# but sides can't be accessed out here 

roll có không gian tên riêng , nhưng tên trong không gian tên của mô-đun cũng nằm trong phạm vi .


@CarlSmith lưu ý rằng tài liệu Python ban đầu nói điều tương tự: "Phạm vi là vùng văn bản của chương trình Python nơi không gian tên có thể truy cập trực tiếp." Có thể truy cập trực tiếp '' ở đây có nghĩa là một tham chiếu không đủ tiêu chuẩn cho tên cố gắng tìm tên trong không gian tên. "
jonrsharpe 17/2/2015

@CarlSmith ngoài việc bổ sung phạm vi không cục bộ / kèm theo, điều đó có thay đổi nhiều không? Tôi nghĩ rằng chúng ta đang nói điều tương tự - một không gian tên chứa tên và giá trị và phạm vi cho bạn biết không gian tên nào có thể truy cập được.
jonrsharpe 17/2/2015

Tôi đã xóa những bình luận cũ của tôi.
Carl Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.