Hướng dẫn python global object pattern - mô hình đối tượng toàn cầu python

Phán quyết

Giống như một số ngôn ngữ kịch bản khác, Python phân tích mức độ bên ngoài của mỗi mô -đun là mã thông thường. Các câu lệnh, biểu thức, biểu thức, và thậm chí các vòng lặp và điều kiện sẽ thực thi khi mô-đun được nhập. Điều này mang đến một cơ hội tuyệt vời để bổ sung các lớp và chức năng của một mô-đun với các hằng số và cấu trúc dữ liệu mà người gọi sẽ thấy hữu ích-nhưng cũng cung cấp những cám dỗ nguy hiểm: các đối tượng toàn cầu có thể thay đổi có thể kết nối mã xa và hoạt động I/O áp đặt chi phí thời gian nhập khẩu và phản ứng phụ.

Mỗi mô -đun Python là một không gian tên riêng. A & NBSP; Mô -đun như

del calendar.January
print[calendar.January]
2 có thể cung cấp chức năng
del calendar.January
print[calendar.January]
3 mà không mâu thuẫn với, thay thế hoặc ghi đè hàm
del calendar.January
print[calendar.January]
3 hoàn toàn khác nhau được xác định trong mô -đun
del calendar.January
print[calendar.January]
5.

Không gian tên riêng biệt là rất quan trọng để tạo ra một ngôn ngữ lập trình có thể điều khiển được. Nếu các mô -đun Python không phải là không gian tên riêng biệt, bạn sẽ không thể đọc hoặc viết mã Python bằng cách giữ sự chú ý của bạn tập trung vào mô -đun trước mặt bạn - một dòng mã có thể sử dụng hoặc vô tình xung đột với Thư viện tiêu chuẩn hoặc mô-đun của bên thứ ba bạn đã cài đặt. Nâng cấp mô-đun của bên thứ ba có thể phá vỡ toàn bộ chương trình của bạn nếu phiên bản mới xác định một toàn cầu mới mâu thuẫn với bạn. Các lập trình viên bị buộc phải viết mã bằng ngôn ngữ mà không có không gian tên sớm thấy mình gây ra những cái tên toàn cầu với tiền tố, hậu tố và dấu câu thêm trong một cuộc đua tuyệt vọng để giữ cho họ không mâu thuẫn.

Mặc dù mọi chức năng và lớp, tất nhiên, là một đối tượng - trong Python, mọi thứ đều là một đối tượng - mô hình toàn cầu mô -đun cụ thể đề cập đến các trường hợp đối tượng bình thường được đặt tên ở cấp độ toàn cầu của một mô -đun.

Hai mẫu sử dụng mô -đun toàn cầu nhưng đủ quan trọng để đảm bảo các bài viết của riêng họ:

  • Các phương thức tiền đề được tạo khi một mô -đun xây dựng một đối tượng và sau đó gán một hoặc nhiều phương thức ràng buộc đối tượng của đối tượng để đặt tên ở cấp độ toàn cầu của mô -đun. Các tên có thể được sử dụng để gọi các phương thức sau mà không cần phải tự tìm thấy đối tượng. are generated when a module builds an object and then assigns one or more of the object’s bound methods to names at the module’s global level. The names can be used to call the methods later without needing to find the object itself.
  • Mặc dù một đối tượng Sentinel không phải sống trong không gian tên toàn cầu của một mô -đun - một số đối tượng Sentinel được định nghĩa là thuộc tính lớp, trong khi những đối tượng khác là riêng tư và sống bên trong một đóng cửa - nhiều Sentinels, cả trong thư viện tiêu chuẩn và hơn thế nữa, được xác định và Truy cập như mô -đun toàn cầu.Sentinel Object doesn’t have to live in a module’s global namespace — some sentinel objects are defined as class attributes, while others are private and live inside of a closure — many sentinels, both in the Standard Library and beyond, are defined and accessed as module globals.

Bài viết này sẽ bao gồm một số trường hợp phổ biến khác.

Mẫu không đổi

Các mô -đun thường gán số hữu ích, chuỗi và các giá trị khác cho tên trong phạm vi toàn cầu của chúng. Thư viện tiêu chuẩn bao gồm nhiều bài tập như vậy, từ đó chúng tôi có thể trích xuất một vài ví dụ.

January = 1                   # calendar.py
WARNING = 30                  # logging.py
MAX_INTERPOLATION_DEPTH = 10  # configparser.py
SSL_HANDSHAKE_TIMEOUT = 60.0  # asyncio.constants.py
TICK = "'"                    # email.utils.py
CRLF = "\r\n"                 # smtplib.py

Hãy nhớ rằng đây là những hằng số của người Viking chỉ theo nghĩa là các đối tượng là bất biến. Các tên vẫn có thể được chỉ định lại.

import calendar
calendar.January = 13
print[calendar.January]

Hoặc bị xóa, cho vấn đề đó.

del calendar.January
print[calendar.January]

Traceback [most recent call last]:
  ...
AttributeError: module 'calendar' has no attribute 'January'

Ngoài các số nguyên, phao và dây, các hằng số còn bao gồm các thùng chứa bất biến như bộ dữ liệu và bộ đông lạnh:

all_errors = [Error, OSError, EOFError]  # ftplib.py
bytes_types = [bytes, bytearray]         # pickle.py
DIGITS = frozenset["0123456789"]         # sre_parse.py

Các loại dữ liệu bất biến chuyên biệt hơn cũng đóng vai trò là hằng số:

_EPOCH = datetime[1970, 1, 1, tzinfo=timezone.utc]  # datetime

Trong những dịp hiếm hoi, một mô -đun toàn cầu mà mã rõ ràng không bao giờ có ý định sửa đổi sử dụng cấu trúc dữ liệu có thể thay đổi. Các bộ có thể thay đổi đơn giản là phổ biến trong mã trước khi phát minh ra

del calendar.January
print[calendar.January]
6. Từ điển vẫn được sử dụng cho đến ngày nay bởi vì, than ôi, thư viện tiêu chuẩn không cung cấp một từ điển đóng băng.

# socket.py
_blocking_errnos = { EAGAIN, EWOULDBLOCK }

# locale.py
windows_locale = {
  0x0436: "af_ZA", # Afrikaans
  0x041c: "sq_AL", # Albanian
  0x0484: "gsw_FR",# Alsatian - France
  ...
  0x0435: "zu_ZA", # Zulu
}

Các hằng số thường được giới thiệu dưới dạng tái cấu trúc: lập trình viên thông báo rằng cùng một giá trị

del calendar.January
print[calendar.January]
7 xuất hiện nhiều lần trong mã của chúng và do đó giới thiệu hằng số
del calendar.January
print[calendar.January]
8 cho giá trị thay thế. Mỗi cách sử dụng tên bây giờ sẽ phải chịu chi phí nhỏ của việc tìm kiếm vào phạm vi toàn cầu, nhưng điều này được cân bằng bởi một vài lợi thế. Tên liên tục hiện nay ghi lại ý nghĩa của giá trị, cải thiện khả năng đọc của mã. Và câu lệnh gán không liên tục hiện cung cấp một vị trí duy nhất trong đó giá trị có thể được chỉnh sửa trong tương lai mà không cần phải sử dụng mã cho từng nơi
del calendar.January
print[calendar.January]
7 được sử dụng.

Những lợi thế này đủ trọng lượng để đôi khi một hằng số được giới thiệu ngay cả đối với một giá trị mà chỉ sử dụng một lần, nâng một nghĩa đen được ẩn sâu trong mã vào khả năng hiển thị như một toàn cầu.

Một số lập trình viên đặt các bài tập không đổi gần với mã sử dụng chúng; Những người khác đặt tất cả các hằng số ở đầu tệp. Trừ khi một hằng số được đặt rất gần với mã của nó đến nỗi nó sẽ luôn luôn theo quan điểm của người đọc con người, thì việc đặt các hằng số ở đầu mô -đun có thể thân thiện hơn Hỗ trợ chuyển đổi để định nghĩa.

Một loại hằng số khác không được hướng vào bên trong, hướng tới mã trong chính mô -đun, mà ra ngoài như là một phần của API mô -đun được quảng cáo. A & nbsp; hằng số như

Traceback [most recent call last]:
  ...
AttributeError: module 'calendar' has no attribute 'January'
0 từ mô -đun
Traceback [most recent call last]:
  ...
AttributeError: module 'calendar' has no attribute 'January'
1 cung cấp các lợi thế của hằng số cho người gọi: mã sẽ dễ đọc hơn và giá trị không đổi có thể được điều chỉnh sau này mà không cần người gọi nào cần chỉnh sửa mã của họ.

Bạn có thể mong đợi rằng một không đổi dành cho việc sử dụng mô -đun, nhưng không dành cho người gọi, sẽ luôn bắt đầu với một dấu gạch dưới để đánh dấu nó riêng tư. Nhưng các lập trình viên Python không nhất quán trong việc đánh dấu các hằng số, có lẽ vì chi phí cần phải giữ một liên tục mãi mãi vì người gọi có thể đã quyết định sử dụng nó nhỏ hơn chi phí có chức năng trợ giúp hoặc API Lớp API mãi mãi bị khóa.

Tính toán thời gian nhập khẩu

Đôi khi các hằng số được giới thiệu cho hiệu quả, để tránh tính toán lại một giá trị mỗi khi mã thời gian được gọi. Ví dụ, mặc dù các hoạt động toán học liên quan đến các số theo nghĩa đen trên thực tế được tối ưu hóa trong tất cả các triển khai Python hiện đại, các nhà phát triển vẫn thường cảm thấy thoải mái hơn khi nói rõ rằng toán học nên được thực hiện vào thời điểm nhập bằng cách gán kết quả cho một mô -đun toàn cầu:

# zipfile.py
ZIP_FILECOUNT_LIMIT = [1 

Bài Viết Liên Quan

Chủ Đề