Hướng dẫn python dataclass vs simplenamespace - python dataclass so với simplenamespace

Câu trả lời ngắn gọn là tất cả đều được PEP 557 bao gồm một chút câu hỏi của bạn ...

Why?

  1. Để tận dụng PEP 526 để cung cấp một cách đơn giản để xác định các lớp đó.
  2. Để hỗ trợ người kiểm tra loại tĩnh.

Làm thế nào để chọn khi nào nên sử dụng chúng?

PEP khá rõ ràng rằng họ không phải là người thay thế và mong đợi các giải pháp khác có vị trí riêng của họ.

Giống như bất kỳ quyết định thiết kế nào khác, do đó bạn sẽ cần quyết định chính xác những tính năng nào bạn quan tâm. Nếu điều đó bao gồm những điều sau đây, bạn chắc chắn không muốn DataClasses.

Trường hợp không phù hợp để sử dụng các lớp dữ liệu?

Khả năng tương thích API với các bộ dữ liệu hoặc dicts là bắt buộc. Xác thực loại vượt quá mức được cung cấp bởi PEPS 484 và 526 là bắt buộc, hoặc xác thực hoặc chuyển đổi giá trị là bắt buộc.

Điều đó nói rằng, điều tương tự cũng đúng với Simplenamespace, vậy chúng ta có thể nhìn vào điều gì khác để quyết định? Hãy xem xét kỹ hơn các tính năng bổ sung được cung cấp bởi DataClasses ...

Định nghĩa hiện tại của Simplenamespace như sau:

Một lớp con đối tượng đơn giản cung cấp quyền truy cập thuộc tính vào không gian tên của nó, cũng như một repr.

Các tài liệu Python sau đó tiếp tục nói rằng nó cung cấp một triển khai đơn giản __init__, __repr____eq__. So sánh điều này với PEP 557, DataClasses cũng cung cấp cho bạn các tùy chọn cho:

  • Đặt hàng - So sánh lớp như thể nó là một bộ phận của các trường của nó, theo thứ tự.
  • tính bất biến - Trường hợp gán cho các trường sẽ tạo ra một ngoại lệ
  • Kiểm soát băm - mặc dù điều này không được khuyến khích.

Rõ ràng, sau đó, bạn nên sử dụng DataClasses nếu bạn quan tâm đến việc đặt hàng hoặc bất biến [hoặc cần điều khiển băm thích hợp].

Các trường hợp sử dụng khác?

Không ai có thể nhìn thấy, mặc dù bạn có thể lập luận rằng "tại sao?" Bao gồm các trường hợp sử dụng khác.

Vui lòng xem xét đăng ký LWN

Đăng ký là huyết mạch của LWN.NET. Nếu bạn đánh giá cao nội dung này và muốn xem nhiều hơn về nó, đăng ký của bạn sẽ giúp đảm bảo rằng LWN tiếp tục phát triển mạnh. Vui lòng truy cập trang này để tham gia và giữ LWN trên mạng.

Lớp Simplenamespace của Python cung cấp một cách dễ dàng để một lập trình viên tạo một đối tượng để lưu trữ các giá trị dưới dạng các thuộc tính mà không tạo ra lớp [gần như trống] của chúng. Mặc dù nó hữu ích [và được sử dụng] ở dạng hiện tại, Raymond Hettinger nghĩ rằng nó có thể tốt hơn. Anh ta muốn thấy các móc được sử dụng bởi các ánh xạ [ví dụ: từ điển] được thêm vào lớp, để các thuộc tính có thể được thêm và loại bỏ bằng X.A hoặc X ['A']. Nó sẽ mang lại lợi ích cho việc xử lý JSON và nhiều hơn trong ngôn ngữ.

Một không gian đơn giản cung cấp một cơ chế để khởi tạo một đối tượng có thể giữ các thuộc tính và không có gì khác. Trong thực tế, nó là một lớp trống với fancier __init __ [] và __repr __ [] hữu ích __ []:

    >>> from types import SimpleNamespace
    >>> sn = SimpleNamespace[x = 1, y = 2]
    >>> sn
    namespace[x=1, y=2]
    >>> sn.z = 'foo'
    >>> del[sn.x]
    >>> sn
    namespace[y=2, z='foo']

Hettinger đã đề xuất ý tưởng của mình cho danh sách gửi thư Python-Dev vào giữa tháng Tư. Ông mô tả nó như sau:

SimplenAmespace [] thực sự tốt trong việc cung cấp cho phép truy cập kiểu thuộc tính. Tôi muốn làm cho chức năng đó có sẵn cho mô -đun JSON [hoặc bất cứ thứ gì khác chấp nhận một dict tùy chỉnh] bằng cách thêm các phương thức ma thuật cho ánh xạ để điều này hoạt động:

     catalog = json.load[f, object_hook=SimpleNamespace]
     print[catalog['clothing']['mens']['shoes']['extra_wide']['quantity']] # currently possible with dict[]
     print[catalog.clothing.mens.shoes.extra_wide.quantity]                # proposed with SimpleNamespace[]
     print[catalog.clothing.boys['3t'].tops.quantity]                      # would also be supported

Các

json.load[]

chức năng sẽ sử dụng

Object_hook

để tạo

Simplenamespace

Đối tượng hơn là từ điển. Sau đó, một hỗn hợp các hoạt động có thể được sử dụng để truy xuất thông tin từ cấu trúc dữ liệu. Trong thực tế,

json.load[]

sẽ sử dụng quyền truy cập kiểu từ điển để lưu trữ mọi thứ vào cấu trúc dữ liệu và Hettinger muốn khả năng làm việc với nó bằng cách sử dụng ký hiệu thuộc tính.

Có những ví dụ về mã sản xuất làm điều này, ông nói, nhưng mỗi người dùng cần phải phát minh lại bánh xe: "Đây là loại [A] Bummer vì các lớp con tùy chỉnh là một nỗi đau để viết, không chuẩn, và Nói chung là hơi chậm. " Anh ta đã bắt đầu với một yêu cầu tính năng trong trình theo dõi lỗi Python, nhưng các phản hồi ở đó đề nghị thêm một lớp mới.

. Vui lòng thêm nhiều bình luận để chúng tôi có thể tìm ra cách tốt nhất để cung cấp chức năng mạnh mẽ này.

Guido Van Rossum nghĩ rằng loại sử dụng không đặc biệt là Pythonic, và không thực sự ủng hộ việc truyền bá nó:

Tôi đã thấy mô hình này rất nhiều ở một nhà tuyển dụng trong quá khứ, và mặc dù có sự tiện lợi rõ ràng, tôi đã xem nó như một người chống lại: vì mọi người mong đợi ngữ nghĩa Python, thật đáng ngạc nhiên khi đọc mã viết foo.bar và sau đó đọc trở lại foo ['Bar']. Chúng ta không nên cố gắng nhập mô hình đối tượng của JavaScript vào Python.

Kyle Stanley tự hỏi liệu tính năng này có hợp lý trong mô -đun JSON không; "Đó có vẻ như là vị trí hữu ích và trực quan nhất cho ký hiệu dấu chấm". Anh ấy nghĩ rằng người dùng JSON sẽ không ngạc nhiên bởi phong cách sử dụng đó, nhưng Van Rossum không đồng ý:

Chà, với tư cách là người dùng JSON trong Python I * sẽ * ngạc nhiên bởi nó, vì ký hiệu JSON thực tế sử dụng Dicts và hầu hết các mã Python tôi đã thấy rằng dữ liệu JSON truy cập trực tiếp sử dụng ký hiệu Dict. Trường hợp bạn thấy ký hiệu DOT là nếu Dict JSON thô được xác minh và chuyển đổi thành một đối tượng thông thường [thường là với sự trợ giúp của một số thư viện lược đồ], nhưng có ký hiệu dict là đáng nghi ngờ.

Một số người khác đồng ý rằng tính đối ngẫu của đối tượng và truy cập từ điển không phù hợp với Python, nhưng vẫn còn một vấn đề cần giải quyết, vì Hettinger lưu ý: " dấu ngoặc và dấu ngoặc kép ". Victor Stinner đã liệt kê một số ít các dự án khác nhau từ Chỉ số gói Python [PYPI] cung cấp một số hoặc tất cả các tính năng mong muốn, nhưng anh ta không thấy rằng bất kỳ ai trong số đó đã "được thử nghiệm chiến đấu và đạt được đủ phổ biến" mà họ nên được xem xét cho thư viện tiêu chuẩn.

Stinner [và những người khác trong luồng] đã chỉ vào thư viện GLOM là một trong đó có thể được sử dụng để làm việc với dữ liệu JSON được lồng sâu. Nhưng mô hình "attrdict" khá phổ biến, như Hettinger đã chỉ ra. GLOM có thể làm nhiều thứ hơn, nhưng nó không thể tự do trộn và kết hợp hai loại truy cập như Hettinger muốn.

Có một số người nghĩ rằng có thể hợp lý cho mô -đun JSON để cung cấp chức năng, như Stanley đã đề xuất, bao gồm cả Van Rossum, người dường như đi vào ý tưởng này. Glenn Linderman hỗ trợ thêm tính năng trong nhận xét báo cáo lỗi; Anh ấy nghĩ rằng nó rất hữu ích vượt xa Json. "Một tính năng như vậy là quá thực tế không phải là Pythonic." Tương tự, Cameron Simpson nghĩ rằng nó sẽ bổ sung tốt:

Tôi với Raymond ở đây. Tôi nghĩ rằng vị trí của tôi là không giống như hầu hết các lớp, Simplenamespace có ngữ nghĩa rất đơn giản và không có cơ sở __getItem__, do đó, việc tạo bản đồ __getItem__ cho __getattr__ có vẻ ảnh hưởng thấp.

Đúng là việc thêm chức năng giống như từ điển vào Simplenamespace sẽ không ảnh hưởng đến mã hiện có, nhưng hầu hết trong chuỗi dường như vẫn chống lại việc thêm tính năng vào lớp đó. Eric Snow đặt nó theo cách này:

Hãy nhớ rằng tôi đã thêm Simplenamespace khi thực hiện đề xuất tăng cường PEP [Python] 421, để sử dụng cho "sys. Implementation" mới. Toàn bộ vấn đề là giữ cho nó đơn giản, như các tài liệu đề xuất.

Có lẽ gợi ý cấp tiến nhất đến từ Rob Cliffe. Anh ta nghĩ rằng có thể có ý nghĩa khi thêm một nhà điều hành mới vào ngôn ngữ [có lẽ là ".."] mà không có việc thực hiện mặc định. Điều đó sẽ cho phép các lớp xác định toán tử cho chính họ:

Sau đó, trong một lớp cụ thể, bạn có thể thực hiện x..Y có nghĩa là x ['y'] và sau đó bạn có thể viết

    obj..abc..def..ghi

Vẫn khá súc tích, nhưng cảnh báo rằng những gì đang xảy ra không phải là tra cứu thuộc tính bình thường.

Tuy nhiên, như Stinner đã chỉ ra rằng và một số bài viết đầu cơ khác có thể thuộc về một chủ đề Ideas Python. Dường như không có khả năng Simplenamespace sẽ không nhận được tính năng được thêm vào bất cứ lúc nào sớm hoặc hoàn toàn. Có đủ sự phản đối để tạo ra sự thay đổi đó, nhưng có sự công nhận về vấn đề này, vì vậy một số giải pháp khác có thể xảy ra. Nó sẽ, có lẽ, cần điều trị PEP, mặc dù; Một chuyến thăm tới Python-Ideas cũng có thể đang ở ngoài khơi.


Mục nhập chỉ mục cho bài viết này
PythonCải tiến

[Đăng nhập để gửi bình luận]

Chủ Đề