Lớp dữ liệu là gì và chúng khác với các lớp thông thường như thế nào?

170
kingJulian 2017-12-24 09:15.

Với PEP 557, các lớp dữ liệu được đưa vào thư viện tiêu chuẩn python.

Họ sử dụng trình @dataclasstrang trí và chúng được cho là "các cặp tên có thể thay đổi với mặc định" nhưng tôi không thực sự chắc chắn rằng tôi hiểu điều này thực sự có nghĩa là gì và chúng khác với các lớp thông thường như thế nào.

Chính xác thì các lớp dữ liệu python là gì và khi nào thì tốt nhất để sử dụng chúng?

4 answers

178
Martijn Pieters 2017-12-24 09:22.

Các lớp dữ liệu chỉ là các lớp thông thường hướng tới trạng thái lưu trữ, nhiều hơn là chứa rất nhiều logic. Mỗi khi bạn tạo một lớp chủ yếu bao gồm các thuộc tính, bạn đã tạo một lớp dữ liệu.

Những gì dataclassesmô-đun làm là giúp tạo các lớp dữ liệu dễ dàng hơn . Nó sẽ chăm sóc rất nhiều tấm nồi hơi cho bạn.

Điều này đặc biệt quan trọng khi lớp dữ liệu của bạn phải có thể băm được; điều này đòi hỏi một __hash__phương pháp cũng như một __eq__phương pháp. Nếu bạn thêm một __repr__phương thức tùy chỉnh để dễ gỡ lỗi, điều đó có thể trở nên khá dài dòng:

class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def __init__(
            self, 
            name: str, 
            unit_price: float,
            quantity_on_hand: int = 0
        ) -> None:
        self.name = name
        self.unit_price = unit_price
        self.quantity_on_hand = quantity_on_hand

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

    def __repr__(self) -> str:
        return (
            'InventoryItem('
            f'name={self.name!r}, unit_price={self.unit_price!r}, '
            f'quantity_on_hand={self.quantity_on_hand!r})'

    def __hash__(self) -> int:
        return hash((self.name, self.unit_price, self.quantity_on_hand))

    def __eq__(self, other) -> bool:
        if not isinstance(other, InventoryItem):
            return NotImplemented
        return (
            (self.name, self.unit_price, self.quantity_on_hand) == 
            (other.name, other.unit_price, other.quantity_on_hand))

Với dataclassesbạn có thể giảm nó thành:

from dataclasses import dataclass

@dataclass(unsafe_hash=True)
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

Lớp trang trí tương tự cũng có thể tạo ra các phương pháp so sánh ( __lt__, __gt__, vv) và xử lý bất biến.

namedtuplecác lớp cũng là các lớp dữ liệu, nhưng không thay đổi theo mặc định (cũng như là các chuỗi). dataclasseslinh hoạt hơn nhiều trong vấn đề này và có thể dễ dàng được cấu trúc để chúng có thể thực hiện cùng một vai trò như một namedtuplelớp .

PEP được lấy cảm hứng từ attrsdự án , có thể làm được nhiều hơn thế (bao gồm vị trí, trình xác thực, trình chuyển đổi, siêu dữ liệu, v.v.).

Nếu bạn muốn xem một số ví dụ, gần đây tôi đã sử dụng dataclassesmột số giải pháp Advent of Code của mình , hãy xem các giải pháp cho ngày 7 , ngày 8 , ngày 11ngày 20 .

Nếu bạn muốn sử dụng dataclassesmô-đun trong các phiên bản Python <3.7, thì bạn có thể cài đặt mô-đun được báo cáo ngược (yêu cầu 3.6) hoặc sử dụng attrsdự án được đề cập ở trên.

89
pylang 2018-09-12 09:38.

Tổng quat

Câu hỏi đã được giải quyết. Tuy nhiên, câu trả lời này bổ sung thêm một số ví dụ thực tế để hỗ trợ hiểu biết cơ bản về kính dữ liệu.

Chính xác thì các lớp dữ liệu python là gì và khi nào thì tốt nhất để sử dụng chúng?

  1. bộ tạo mã : tạo mã chương trình; bạn có thể chọn triển khai các phương thức đặc biệt trong một lớp thông thường hoặc để một kính dữ liệu tự động triển khai chúng.
  2. vùng chứa dữ liệu : các cấu trúc lưu giữ dữ liệu (ví dụ: bộ giá trị và bộ số), thường có quyền truy cập thuộc tính, có dấu chấm, chẳng hạn như các lớp namedtuplevà các cấu trúc khác .

"các cặp có tên có thể thay đổi với [s] mặc định"

Đây là ý nghĩa của cụm từ sau:

  • có thể thay đổi : theo mặc định, các thuộc tính dataclass có thể được gán lại. Bạn có thể tùy ý biến chúng thành bất biến (xem Ví dụ bên dưới).
  • Nametuple : bạn có quyền truy cập thuộc tính dạng chấm, giống như một namedtuplehoặc một lớp thông thường.
  • default : bạn có thể gán giá trị mặc định cho các thuộc tính.

So với các lớp thông thường, bạn chủ yếu tiết kiệm khi nhập mã soạn sẵn.


Đặc trưng

Đây là tổng quan về các tính năng của dataclass (TL; DR? Xem Bảng Tóm tắt trong phần tiếp theo).

Những gì bạn nhận được

Đây là các tính năng bạn nhận được theo mặc định từ dataclasses.

Thuộc tính + Đại diện + So sánh

import dataclasses


@dataclasses.dataclass
#@dataclasses.dataclass()                                       # alternative
class Color:
    r : int = 0
    g : int = 0
    b : int = 0

Các giá trị mặc định này được cung cấp bằng cách tự động đặt các từ khóa sau thành True:

@dataclasses.dataclass(init=True, repr=True, eq=True)

Những gì bạn có thể bật

Các tính năng bổ sung có sẵn nếu các từ khóa thích hợp được đặt thành True.

Đặt hàng

@dataclasses.dataclass(order=True)
class Color:
    r : int = 0
    g : int = 0
    b : int = 0

Các phương thức sắp xếp hiện được thực hiện (nạp chồng toán tử < > <= >=:), tương tự như functools.total_orderingvới các bài kiểm tra bình đẳng mạnh hơn.

Có thể thay đổi, có thể thay đổi

@dataclasses.dataclass(unsafe_hash=True)                        # override base `__hash__`
class Color:
    ...

Mặc dù đối tượng có khả năng thay đổi (có thể không mong muốn), một hàm băm được thực hiện.

Có thể thay đổi, bất biến

@dataclasses.dataclass(frozen=True)                             # `eq=True` (default) to be immutable 
class Color:
    ...

Hàm băm hiện đã được triển khai và việc thay đổi đối tượng hoặc gán cho các thuộc tính là không được phép.

Nhìn chung, đối tượng có thể được băm nếu một trong hai unsafe_hash=Truehoặc frozen=True.

Xem thêm bảng logic băm ban đầu với nhiều chi tiết hơn.

Những gì bạn không nhận được

Để có được các tính năng sau, các phương pháp đặc biệt phải được triển khai thủ công:

Mở gói

@dataclasses.dataclass
class Color:
    r : int = 0
    g : int = 0
    b : int = 0

    def __iter__(self):
        yield from dataclasses.astuple(self)

Tối ưu hóa

@dataclasses.dataclass
class SlottedColor:
    __slots__ = ["r", "b", "g"]
    r : int
    g : int
    b : int

Kích thước đối tượng hiện đã giảm:

>>> imp sys
>>> sys.getsizeof(Color)
1056
>>> sys.getsizeof(SlottedColor)
888

Trong một số trường hợp, __slots__cũng cải thiện tốc độ tạo phiên bản và truy cập thuộc tính. Ngoài ra, các vị trí không cho phép các nhiệm vụ mặc định; nếu không, a ValueErrorđược nâng lên.

Xem thêm về các vị trí trong bài đăng blog này .


Bảng tóm tắt

+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
|       Feature        |       Keyword        |                      Example                       |           Implement in a Class          |
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
| Attributes           |  init                |  Color().r -> 0                                    |  __init__                               |
| Representation       |  repr                |  Color() -> Color(r=0, g=0, b=0)                   |  __repr__                               |
| Comparision*         |  eq                  |  Color() == Color(0, 0, 0) -> True                 |  __eq__                                 |
|                      |                      |                                                    |                                         |
| Order                |  order               |  sorted([Color(0, 50, 0), Color()]) -> ...         |  __lt__, __le__, __gt__, __ge__         |
| Hashable             |  unsafe_hash/frozen  |  {Color(), {Color()}} -> {Color(r=0, g=0, b=0)}    |  __hash__                               |
| Immutable            |  frozen + eq         |  Color().r = 10 -> TypeError                       |  __setattr__, __delattr__               |
|                      |                      |                                                    |                                         |
| Unpacking+           |  -                   |  r, g, b = Color()                                 |   __iter__                              |
| Optimization+        |  -                   |  sys.getsizeof(SlottedColor) -> 888                |  __slots__                              |
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+

+ Các phương thức này không được tạo tự động và yêu cầu thực hiện thủ công trong một dataclass.

* __ne__ không cần thiết và do đó không được thực hiện .


Tính năng bổ sung

Hậu khởi tạo

@dataclasses.dataclass
class RGBA:
    r : int = 0
    g : int = 0
    b : int = 0
    a : float = 1.0

    def __post_init__(self):
        self.a : int =  int(self.a * 255)


RGBA(127, 0, 255, 0.5)
# RGBA(r=127, g=0, b=255, a=127)

Di sản

@dataclasses.dataclass
class RGBA(Color):
    a : int = 0

Chuyển đổi

Chuyển đổi một kính dữ liệu thành một bộ hoặc một chính tả, một cách đệ quy :

>>> dataclasses.astuple(Color(128, 0, 255))
(128, 0, 255)
>>> dataclasses.asdict(Color(128, 0, 255))
{'r': 128, 'g': 0, 'b': 255}

Hạn chế


Người giới thiệu

  • Bài nói chuyện của R. Hettinger trên Dataclasses: Trình tạo mã để kết thúc tất cả các trình tạo mã
  • Bài nói chuyện của T. Hunner về Lớp học dễ dàng hơn: Lớp học Python không có tất cả những gì nguy hiểm
  • Tài liệu của Python về chi tiết băm
  • Hướng dẫn của Real Python về Hướng dẫn cơ bản về lớp dữ liệu trong Python 3.7
  • Bài đăng trên blog của A. Shaw về Chuyến tham quan ngắn gọn về các lớp dữ liệu Python 3.7
  • Kho lưu trữ github của E. Smith trên dataclasses
3
prosti 2019-05-24 09:12.

Hãy xem xét lớp học đơn giản này Foo

from dataclasses import dataclass
@dataclass
class Foo:    
    def bar():
        pass  

Đây là dir()so sánh được tích hợp sẵn. Ở bên trái là Fookhông có trình trang trí @dataclass và ở bên phải là không có trình trang trí @dataclass.

Đây là một khác biệt khác, sau khi sử dụng inspectmô-đun để so sánh.

2
Mahmoud Hanafy 2017-12-24 09:21.

Từ thông số kỹ thuật PEP :

Một trình trang trí lớp được cung cấp để kiểm tra định nghĩa lớp cho các biến có chú thích kiểu như được định nghĩa trong PEP 526, "Cú pháp cho chú thích biến". Trong tài liệu này, các biến như vậy được gọi là trường. Sử dụng các trường này, trình trang trí thêm các định nghĩa phương thức đã tạo vào lớp để hỗ trợ khởi tạo phiên bản, đại diện, các phương thức so sánh và các phương thức tùy chọn khác như được mô tả trong phần Đặc tả. Một lớp như vậy được gọi là Lớp Dữ liệu, nhưng thực sự không có gì đặc biệt về lớp: trình trang trí thêm các phương thức đã tạo vào lớp và trả về cùng một lớp mà nó đã được cấp.

Các @dataclassmáy phát điện bổ sung thêm phương thức cho lớp mà bạn muốn bằng cách khác xác định mình như __repr__, __init__, __lt__, và __gt__.

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Desiree Rogers, trái, và Cheryl Mayberry McKissack Chuyển sang, Fenty Beauty và Pat McGrath, có một đế chế làm đẹp mới do phụ nữ làm chủ đang trỗi dậy. Sau thương vụ mua lại mỹ phẩm Black Opal vào tháng 9, đội ngũ quyền lực của Giám đốc điều hành công ty Desiree Rogers và Chủ tịch Cheryl Mayberry McKissack đã thông báo mua lại thương hiệu làm đẹp tiên phong Fashion Fair từ người sáng lập Johnson Publishing Company (JPC).

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Đối với những người có quá nhiều thời gian, tiệc tiết lộ giới tính là một cách thú vị để không cần áp đặt những định kiến ​​hạn chế lên thai nhi trước một đối tượng bạn bè giả vờ quan tâm một cách lịch sự. Tuy nhiên, việc chỉ dựa vào những chiếc bánh nướng có màu nhân tạo để biểu thị một tiếng hoo-ha hoặc một đứa trẻ đi tè đã trở nên xa xỉ trong các bậc cha mẹ trên Instagram.

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Hôm thứ Tư, cựu Bộ trưởng An ninh Nội địa Kirstjen Nielsen vì một lý do nào đó đã được đưa ra một diễn đàn để phát biểu tại Hội nghị thượng đỉnh Những người phụ nữ quyền lực nhất của Fortune. Và có thể đoán trước được, người phụ nữ giám sát các nỗ lực (đang diễn ra) của chính quyền Trump nhằm chia cắt các gia đình ở biên giới đã sử dụng thời gian của mình như một cơ hội để tự bảo vệ mình và tự nhận mình là người — và hãy hít thở sâu ở đây — “đã nói sự thật với quyền lực.

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Vì thế hệ mới nhất của chiếc xe điều chỉnh được yêu thích trên thế giới hiện đã có mặt tại đây, nên chỉ có điều kiện là Toyota Racing Development sẽ đưa phiên bản Supra thế hệ thứ năm sửa đổi của riêng mình đến SEMA vào tháng tới. Toyota đã cho chúng tôi một gợi ý về những gì sẽ xảy ra trong tuần này: một chiếc Concept GR Supra 3000GT hiện đại.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language