Lớp dữ liệu chung của Python

dataclasses là một giải pháp thay thế đơn giản hơn cho

from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
57 từ thư viện chuẩn python.
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
58 hoạt động với nó ngay lập tức. Như với tất cả các ví dụ trước, chúng tôi khuyên bạn nên biến các phiên bản của mình thành bất biến. Thư viện
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
59 có hỗ trợ hạng nhất cho tính bất biến. Kích hoạt cài đặt
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
60 trên lớp và sử dụng chức năng
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
61 để sao chép các phiên bản của nó

>>> from dataclasses import dataclass, replace
>>> from generics import private

>>> @private
.. @dataclass(frozen=True)
.. class User:
..     name: str
...
..     def greet(self):
..         return f"Hello, {self.name}"
...
..     def rename(self, name):
..         return replace(self, name=name)

>>> User
Private::User

>>> user = User("Jeff")
>>> user
Private::User(name='Jeff')

>>> user.greet()
'Hello, Jeff'

>>> user.rename("Kate")
Private::User(name='Kate')

— ⭐ —

Một tính năng mới và thú vị sắp có trong Python 3. 7 là lớp dữ liệu. Lớp dữ liệu là lớp thường chứa chủ yếu là dữ liệu, mặc dù thực sự không có bất kỳ hạn chế nào. Nó được tạo bằng trình trang trí

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
8 mới, như sau

from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str

Ghi chú. Mã này, cũng như tất cả các ví dụ khác trong hướng dẫn này, sẽ chỉ hoạt động trong Python 3. 7 trở lên

Một lớp dữ liệu đi kèm với chức năng cơ bản đã được triển khai. Chẳng hạn, bạn có thể khởi tạo, in và so sánh các thể hiện của lớp dữ liệu ngay lập tức

>>>

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True

So sánh điều đó với một lớp học bình thường. Một lớp thông thường tối thiểu sẽ trông giống như thế này

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit

Mặc dù đây không phải là nhiều mã để viết, nhưng bạn đã có thể thấy các dấu hiệu của nỗi đau soạn sẵn.

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
9 và
>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
0 đều được lặp lại ba lần chỉ để khởi tạo một đối tượng. Hơn nữa, nếu bạn cố gắng sử dụng lớp đơn giản này, bạn sẽ nhận thấy rằng biểu diễn của các đối tượng không mang tính mô tả lắm, và vì lý do nào đó, nữ hoàng trái tim không giống với nữ hoàng trái tim

>>>

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False

Có vẻ như các lớp dữ liệu đang hỗ trợ chúng tôi đằng sau hậu trường. Theo mặc định, các lớp dữ liệu triển khai phương thức

>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
1 để cung cấp biểu diễn chuỗi đẹp mắt và phương thức
>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
2 có thể thực hiện so sánh đối tượng cơ bản. Để lớp
>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
3 bắt chước lớp dữ liệu ở trên, bạn cũng cần thêm các phương thức này

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
1

Trong hướng dẫn này, bạn sẽ tìm hiểu chính xác những tiện ích mà lớp dữ liệu cung cấp. Ngoài các biểu diễn và so sánh đẹp mắt, bạn sẽ thấy

  • Cách thêm giá trị mặc định vào các trường lớp dữ liệu
  • Cách các lớp dữ liệu cho phép sắp xếp thứ tự các đối tượng
  • Cách biểu diễn dữ liệu bất biến
  • Cách các lớp dữ liệu xử lý kế thừa

Chúng ta sẽ sớm tìm hiểu sâu hơn về các tính năng đó của các lớp dữ liệu. Tuy nhiên, bạn có thể nghĩ rằng bạn đã nhìn thấy một cái gì đó như thế này trước đây

Tải xuống miễn phí. Nhận một chương mẫu từ Thủ thuật Python. Cuốn sách chỉ cho bạn các phương pháp hay nhất về Python với các ví dụ đơn giản mà bạn có thể áp dụng ngay lập tức để viết mã Pythonic + đẹp hơn

Các lựa chọn thay thế cho các lớp dữ liệu

Đối với các cấu trúc dữ liệu đơn giản, có lẽ bạn đã sử dụng một

>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
4 hoặc một
>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
5. Bạn có thể đại diện cho thẻ nữ hoàng trái tim theo một trong hai cách sau

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}

nó hoạt động. Tuy nhiên, nó đặt rất nhiều trách nhiệm lên bạn với tư cách là một lập trình viên

  • Bạn cần nhớ rằng biến
    >>> queen_of_hearts_tuple[0]  # No named access
    'Q'
    >>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
    'Hearts'
    
    6 đại diện cho một quân bài
  • Đối với phiên bản
    >>> queen_of_hearts_tuple[0]  # No named access
    'Q'
    >>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
    'Hearts'
    
    4, bạn cần nhớ thứ tự của các thuộc tính. Viết
    >>> queen_of_hearts_tuple[0]  # No named access
    'Q'
    >>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
    'Hearts'
    
    8 sẽ làm rối chương trình của bạn nhưng có thể không cung cấp cho bạn một thông báo lỗi dễ hiểu
  • Nếu bạn sử dụng phiên bản
    >>> queen_of_hearts_tuple[0]  # No named access
    'Q'
    >>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
    'Hearts'
    
    5, bạn phải đảm bảo rằng tên của các thuộc tính phải thống nhất. Ví dụ:
    >>> queen_of_hearts_tuple = ('Q', 'Hearts')
    >>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
    
    90 sẽ không hoạt động như mong đợi

Hơn nữa, sử dụng các cấu trúc này không phải là lý tưởng

>>>

>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'

Một sự thay thế tốt hơn là

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91. Nó từ lâu đã được sử dụng để tạo các cấu trúc dữ liệu nhỏ có thể đọc được. Trên thực tế, chúng ta có thể tạo lại ví dụ về lớp dữ liệu ở trên bằng cách sử dụng một
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 như thế này

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
9

Định nghĩa này của

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
93 sẽ cho kết quả chính xác giống như ví dụ về
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
94 của chúng tôi đã làm

>>>

from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
6

Vậy tại sao lại bận tâm với các lớp dữ liệu? . Đồng thời,

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 có một số tính năng khác không nhất thiết phải được mong muốn. Theo thiết kế, một
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 là một bộ thông thường. Điều này có thể được nhìn thấy trong các so sánh, ví dụ

>>>

from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
9

Mặc dù điều này có vẻ là một điều tốt, nhưng việc thiếu nhận thức về loại của chính nó có thể dẫn đến các lỗi tinh vi và khó tìm, đặc biệt là vì nó cũng sẽ vui vẻ so sánh hai lớp

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 khác nhau

>>>

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
0

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 cũng đi kèm với một số hạn chế. Chẳng hạn, thật khó để thêm các giá trị mặc định vào một số trường trong
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91. Một
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 về bản chất cũng là bất biến. Nghĩa là, giá trị của một
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 không bao giờ có thể thay đổi. Trong một số ứng dụng, đây là một tính năng tuyệt vời, nhưng trong các cài đặt khác, sẽ rất tuyệt nếu có nhiều tính năng linh hoạt hơn

>>>

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
1

Các lớp dữ liệu sẽ không thay thế tất cả các cách sử dụng của

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91. Chẳng hạn, nếu bạn cần cấu trúc dữ liệu của mình hoạt động giống như một bộ dữ liệu, thì bộ dữ liệu có tên là một sự thay thế tuyệt vời

Một giải pháp thay thế khác, và là một trong những nguồn cảm hứng cho các lớp dữ liệu, là dự án

from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
63. Với
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
63 đã cài đặt (
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
65), bạn có thể viết một lớp thẻ như sau

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
2

Điều này có thể được sử dụng theo cách chính xác giống như các ví dụ

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
94 và
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
93 trước đó. Dự án
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
63 rất tuyệt và hỗ trợ một số tính năng mà các lớp dữ liệu không có, bao gồm trình chuyển đổi và trình xác thực. Hơn nữa,
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
63 đã xuất hiện được một thời gian và được hỗ trợ trong Python 2. 7 cũng như Python 3. 4 trở lên. Tuy nhiên, vì
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
63 không phải là một phần của thư viện tiêu chuẩn, nên nó sẽ thêm một phần phụ thuộc bên ngoài vào các dự án của bạn. Thông qua các lớp dữ liệu, chức năng tương tự sẽ có sẵn ở mọi nơi

Ngoài

>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
4,
>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
5,
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 và
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
63, còn có nhiều dự án tương tự khác, bao gồm
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
95,
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
96,
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
97,
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
98 và
from dataclasses import dataclass

@dataclass
class DataClassCard:
    rank: str
    suit: str
99. Mặc dù các lớp dữ liệu là một giải pháp thay thế mới tuyệt vời, nhưng vẫn có những trường hợp sử dụng mà một trong các biến thể cũ phù hợp hơn. Chẳng hạn, nếu bạn cần khả năng tương thích với một API cụ thể, mong đợi các bộ dữ liệu hoặc cần chức năng không được hỗ trợ trong các lớp dữ liệu

Loại bỏ các quảng cáo

Các lớp dữ liệu cơ bản

Hãy để chúng tôi quay trở lại các lớp dữ liệu. Ví dụ, chúng tôi sẽ tạo một lớp

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
00 sẽ đại diện cho các vị trí địa lý có tên cũng như kinh độ và vĩ độ

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
3

Điều làm cho lớp dữ liệu này là trình trang trí

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
8 ngay phía trên định nghĩa lớp. Bên dưới dòng
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
02, bạn chỉ cần liệt kê các trường bạn muốn trong lớp dữ liệu của mình. Ký hiệu
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
03 được sử dụng cho các trường đang sử dụng một tính năng mới trong Python 3. 6 gọi là chú thích biến. Chúng tôi sẽ sớm nói thêm về ký hiệu này và lý do tại sao chúng tôi chỉ định các loại dữ liệu như
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
04 và
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
05

Một vài dòng mã đó là tất cả những gì bạn cần. Lớp mới đã sẵn sàng để sử dụng

>>>

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
4

Bạn cũng có thể tạo các lớp dữ liệu tương tự như cách các bộ dữ liệu được đặt tên được tạo. Điều sau đây (gần như) tương đương với định nghĩa của

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
00 ở trên

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
5

Một lớp dữ liệu là một lớp Python thông thường. Điều duy nhất khiến nó khác biệt là nó có các phương thức mô hình dữ liệu cơ bản như

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
07,
>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
1 và
>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
2 được triển khai cho bạn

Giá trị mặc định

Thật dễ dàng để thêm các giá trị mặc định vào các trường của lớp dữ liệu của bạn

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
6

Điều này hoạt động chính xác như thể bạn đã chỉ định các giá trị mặc định trong định nghĩa của phương thức

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
07 của một lớp thông thường

>>>

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
7

Sau này bạn sẽ tìm hiểu về

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
11, cung cấp một cách cung cấp các giá trị mặc định phức tạp hơn

Nhập gợi ý

Cho đến nay, chúng tôi vẫn chưa làm ầm ĩ lên việc các lớp dữ liệu hỗ trợ gõ ra khỏi hộp. Bạn có thể nhận thấy rằng chúng tôi đã xác định các trường bằng gợi ý loại.

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
12 nói rằng
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
13 phải là một chuỗi văn bản (loại
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
04)

Trên thực tế, việc thêm một số kiểu gợi ý là bắt buộc khi xác định các trường trong lớp dữ liệu của bạn. Nếu không có gợi ý kiểu, trường sẽ không phải là một phần của lớp dữ liệu. Tuy nhiên, nếu bạn không muốn thêm các loại rõ ràng vào lớp dữ liệu của mình, hãy sử dụng

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
15

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
8

Mặc dù bạn cần thêm gợi ý kiểu ở một số biểu mẫu khi sử dụng các lớp dữ liệu, nhưng các kiểu này không được thực thi khi chạy. Đoạn mã sau chạy mà không gặp vấn đề gì

>>>

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
9

Đây là cách gõ trong Python thường hoạt động. Python đang và sẽ luôn là một ngôn ngữ được gõ động. Để thực sự bắt lỗi loại, các công cụ kiểm tra loại như Mypy có thể được chạy trên mã nguồn của bạn

Loại bỏ các quảng cáo

Thêm phương pháp

Bạn đã biết rằng một lớp dữ liệu chỉ là một lớp thông thường. Điều đó có nghĩa là bạn có thể tự do thêm các phương thức của riêng mình vào một lớp dữ liệu. Ví dụ: chúng ta hãy tính khoảng cách giữa vị trí này với vị trí khác, dọc theo bề mặt Trái đất. Một cách để làm điều này là sử dụng công thức haversine

Lớp dữ liệu chung của Python

Bạn có thể thêm phương thức

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
16 vào lớp dữ liệu của mình giống như bạn có thể làm với các lớp thông thường

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
0

Nó hoạt động như bạn mong đợi

>>>

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
1

Các lớp dữ liệu linh hoạt hơn

Đến đây, bạn đã thấy một số tính năng cơ bản của lớp dữ liệu. nó cung cấp cho bạn một số phương thức tiện lợi và bạn vẫn có thể thêm các giá trị mặc định và các phương thức khác. Bây giờ bạn sẽ tìm hiểu về một số tính năng nâng cao hơn như tham số cho trình trang trí

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
8 và hàm
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
18. Cùng với nhau, chúng mang lại cho bạn nhiều quyền kiểm soát hơn khi tạo một lớp dữ liệu

Hãy để chúng tôi quay lại ví dụ chơi bài mà bạn đã thấy ở phần đầu của hướng dẫn và thêm một lớp chứa một bộ bài trong khi chúng tôi đang ở đó

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
2

Một bộ bài đơn giản chỉ chứa hai lá bài có thể được tạo như thế này

>>>

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
3

Giá trị mặc định nâng cao

Giả sử bạn muốn cung cấp giá trị mặc định cho

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
19. Ví dụ, sẽ thuận tiện nếu
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
20 tạo một bộ bài 52 lá thông thường (tiếng Pháp). Đầu tiên, chỉ định các cấp bậc và bộ quần áo khác nhau. Sau đó, thêm một hàm
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
21 để tạo danh sách các phiên bản của
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
22

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
4

Để giải trí, bốn bộ quần áo khác nhau được chỉ định bằng các ký hiệu Unicode của chúng

Ghi chú. Ở trên, chúng tôi đã sử dụng các ký tự Unicode như

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
23 trực tiếp trong mã nguồn. Chúng tôi có thể làm điều này vì Python hỗ trợ viết mã nguồn theo UTF-8 theo mặc định. Tham khảo trang này về đầu vào Unicode để biết cách nhập chúng trên hệ thống của bạn. Bạn cũng có thể nhập các ký hiệu Unicode cho các bộ quần áo bằng cách sử dụng các dấu thoát ký tự có tên là
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
24 (như
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
25) hoặc dấu thoát Unicode
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
26 (như
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
27)

Để đơn giản hóa việc so sánh các thẻ sau này, các cấp bậc và bộ đồ cũng được liệt kê theo thứ tự thông thường của chúng

>>>

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
5

Về lý thuyết, bây giờ bạn có thể sử dụng hàm này để chỉ định giá trị mặc định cho

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
28

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
6

Đừng làm điều này. Điều này giới thiệu một trong những mẫu chống phổ biến nhất trong Python. sử dụng các đối số mặc định có thể thay đổi. Vấn đề là tất cả các phiên bản của

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
19 sẽ sử dụng cùng một đối tượng danh sách làm giá trị mặc định của thuộc tính
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
30. Điều này có nghĩa là nếu, giả sử, một thẻ bị xóa khỏi một
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
19, thì thẻ đó cũng biến mất khỏi tất cả các phiên bản khác của
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
19. Trên thực tế, các lớp dữ liệu cố gắng ngăn bạn làm điều này và đoạn mã trên sẽ tăng
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
33

Thay vào đó, các lớp dữ liệu sử dụng thứ gọi là

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
11 để xử lý các giá trị mặc định có thể thay đổi. Để sử dụng
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
11 (và nhiều tính năng thú vị khác của các lớp dữ liệu), bạn cần sử dụng trình xác định
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
18

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
7

Đối số của

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
11 có thể là bất kỳ tham số 0 nào có thể gọi được. Bây giờ thật dễ dàng để tạo một bộ bài đầy đủ

>>>

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
8

Trình xác định

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
18 được sử dụng để tùy chỉnh từng trường của một lớp dữ liệu riêng lẻ. Bạn sẽ thấy một số ví dụ khác sau. Để tham khảo, đây là các thông số mà
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
18 hỗ trợ

  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    40. Giá trị mặc định của trường
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    11. Hàm trả về giá trị ban đầu của trường
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    42. Sử dụng trường trong phương thức
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    07? . )
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    45. Sử dụng trường trong
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    45 của đối tượng? . )
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    48. Bao gồm trường trong so sánh? . )
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    50. Bao gồm trường khi tính toán
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    51? . )
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    53. Một ánh xạ với thông tin về lĩnh vực này

Trong ví dụ về

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
00, bạn đã thấy cách thêm các giá trị mặc định đơn giản bằng cách viết
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
55. Tuy nhiên, nếu bạn cũng muốn tùy chỉnh trường, chẳng hạn để ẩn nó trong
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
45, bạn cần sử dụng tham số
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
40.
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
58. Bạn không được chỉ định cả
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
40 và
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
11

Tham số

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
53 không được sử dụng bởi chính các lớp dữ liệu nhưng có sẵn để bạn (hoặc các gói của bên thứ ba) đính kèm thông tin vào các trường. Trong ví dụ về
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
00, chẳng hạn, bạn có thể chỉ định rằng vĩ độ và kinh độ phải được tính theo độ

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
9

Siêu dữ liệu (và thông tin khác về một trường) có thể được truy xuất bằng cách sử dụng hàm

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
63 (lưu ý số nhiều s)

>>>

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
0

Loại bỏ các quảng cáo

Bạn cần đại diện?

Nhớ lại rằng chúng ta có thể tạo ra bộ bài ngoài không khí mỏng

>>>

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
8

Mặc dù biểu diễn này của một

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
19 là rõ ràng và dễ đọc, nhưng nó cũng rất dài dòng. Tôi đã xóa 48 trong số 52 lá bài trong bộ bài ở đầu ra ở trên. Trên màn hình 80 cột, chỉ cần in toàn bộ
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
19 chiếm 22 dòng. Hãy để chúng tôi thêm một đại diện ngắn gọn hơn. Nói chung, một đối tượng Python có hai biểu diễn chuỗi khác nhau

  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    66 được xác định bởi
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    67 và sẽ trả về một đại diện thân thiện với nhà phát triển của
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    68. Nếu có thể, đây phải là mã có thể tạo lại
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    68. Các lớp dữ liệu làm điều này

  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    70 được xác định bởi
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    71 và sẽ trả về một đại diện thân thiện với người dùng của
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    68. Các lớp dữ liệu không triển khai phương thức
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    73, vì vậy Python sẽ quay trở lại phương thức
    >>> queen_of_hearts_tuple[0]  # No named access
    'Q'
    >>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
    'Hearts'
    
    1

Hãy để chúng tôi thực hiện một đại diện thân thiện với người dùng của một

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
22

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
2

Các lá bài bây giờ trông đẹp hơn nhiều, nhưng bộ bài vẫn dài dòng như ngày nào

>>>

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
3

Để chứng minh rằng có thể thêm phương thức

>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
1 của riêng bạn, chúng tôi sẽ vi phạm nguyên tắc rằng phương thức đó phải trả về mã có thể tạo lại một đối tượng. Xét cho cùng, tính thực tế đánh bại sự thuần khiết. Đoạn mã sau thêm một biểu diễn ngắn gọn hơn của
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
19

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
4

Lưu ý mã xác định

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
78 trong chuỗi định dạng
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
79. Điều đó có nghĩa là chúng tôi rõ ràng muốn sử dụng đại diện
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
80 của mỗi
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
22. Với
>>> queen_of_hearts_tuple[0]  # No named access
'Q'
>>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
'Hearts'
1 mới, đại diện của
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
19 dễ nhìn hơn

>>>

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
5

Đây là một đại diện đẹp hơn của bộ bài. Tuy nhiên, nó đi kèm với một chi phí. Bạn không còn có thể tạo lại bộ bài bằng cách thực hiện biểu diễn của nó. Thông thường, tốt hơn hết là bạn nên triển khai biểu diễn tương tự với

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
73 để thay thế

So sánh thẻ

Trong nhiều trò chơi bài, các quân bài được so sánh với nhau. Ví dụ, trong một trò chơi đánh lừa thông thường, quân bài cao nhất sẽ ăn thua. Vì nó hiện đang được triển khai, lớp

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
22 không hỗ trợ kiểu so sánh này

>>>

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
6

Tuy nhiên, điều này (dường như) dễ khắc phục

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
7

Trình trang trí

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
8 có hai dạng. Cho đến giờ bạn đã thấy biểu mẫu đơn giản trong đó
>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
8 được chỉ định mà không có bất kỳ dấu ngoặc đơn và tham số nào. Tuy nhiên, bạn cũng có thể cung cấp tham số cho trình trang trí
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
88 trong ngoặc đơn. Các tham số sau đây được hỗ trợ

  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    42. Thêm phương thức
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    07? . )
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    45. Thêm phương thức
    >>> queen_of_hearts_tuple[0]  # No named access
    'Q'
    >>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
    'Hearts'
    
    1? . )
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    95. Thêm phương thức
    >>> queen_of_hearts_tuple[0]  # No named access
    'Q'
    >>> queen_of_hearts_dict['suit']  # Would be nicer with .suit
    'Hearts'
    
    2? . )
  • >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    98. Thêm phương thức đặt hàng? . )
  • class RegularCard:
        def __init__(self, rank, suit):
            self.rank = rank
            self.suit = suit
    
    00. Buộc bổ sung phương thức
    class RegularCard:
        def __init__(self, rank, suit):
            self.rank = rank
            self.suit = suit
    
    01? . )
  • class RegularCard:
        def __init__(self, rank, suit):
            self.rank = rank
            self.suit = suit
    
    03. Nếu
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    44, việc gán cho các trường sẽ tạo ra một ngoại lệ. (Mặc định là
    >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
    >>> queen_of_hearts.rank
    'Q'
    >>> queen_of_hearts
    DataClassCard(rank='Q', suit='Hearts')
    >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
    True
    
    99. )

Xem PEP gốc để biết thêm thông tin về từng thông số. Sau khi cài đặt

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
06, các phiên bản của
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
22 có thể được so sánh

>>>

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
8

Làm thế nào là hai thẻ so sánh mặc dù?

Hóa ra các lớp dữ liệu so sánh các đối tượng như thể chúng là các bộ của các trường của chúng. Nói cách khác, quân Hậu cao hơn quân Át vì

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
08 đứng sau
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
09 trong bảng chữ cái

>>>

>>> queen_of_hearts = RegularCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
<__main__.RegularCard object at 0x7fb6eee35d30>
>>> queen_of_hearts == RegularCard('Q', 'Hearts')
False
9

Điều đó không thực sự hiệu quả với chúng tôi. Thay vào đó, chúng ta cần xác định một số loại chỉ mục sắp xếp sử dụng thứ tự của

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
10 và
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
11. Một cái gì đó như thế này

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
10

Để

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
22 sử dụng chỉ số sắp xếp này để so sánh, chúng ta cần thêm trường
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
13 vào lớp. Tuy nhiên, trường này phải được tính tự động từ các trường khác
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
14 và
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
15. Đây chính xác là phương pháp đặc biệt dành cho
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
16. Nó cho phép xử lý đặc biệt sau khi phương thức
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
07 thông thường được gọi

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
11

Lưu ý rằng

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
13 được thêm vào làm trường đầu tiên của lớp. Bằng cách đó, việc so sánh được thực hiện đầu tiên bằng cách sử dụng
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
13 và chỉ khi có mối quan hệ ràng buộc thì các trường khác mới được sử dụng. Sử dụng
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
18, bạn cũng phải chỉ định rằng không nên bao gồm
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
13 như một tham số trong phương thức
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
07 (vì nó được tính toán từ các trường
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
14 và
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
15). Để tránh gây nhầm lẫn cho người dùng về chi tiết triển khai này, có lẽ cũng nên xóa
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
13 khỏi
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
45 của lớp

Cuối cùng, con át chủ bài cao

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
12

Bây giờ bạn có thể dễ dàng tạo một bộ bài được sắp xếp

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
13

Hoặc, nếu bạn không quan tâm đến việc sắp xếp, đây là cách bạn rút ngẫu nhiên 10 lá bài

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
14

Tất nhiên, bạn không cần

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
06 cho điều đó…

Loại bỏ các quảng cáo

Các lớp dữ liệu bất biến

Một trong những tính năng xác định của

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
91 mà bạn đã thấy trước đó là nó không thay đổi. Đó là, giá trị của các lĩnh vực của nó có thể không bao giờ thay đổi. Đối với nhiều loại lớp dữ liệu, đây là một ý tưởng tuyệt vời. Để làm cho một lớp dữ liệu trở nên bất biến, hãy đặt
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
29 khi bạn tạo nó. Ví dụ: sau đây là phiên bản bất biến của lớp
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
00 mà bạn đã thấy trước đó

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
15

Trong lớp dữ liệu cố định, bạn không thể gán giá trị cho các trường sau khi tạo

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
16

Mặc dù vậy, hãy lưu ý rằng nếu lớp dữ liệu của bạn chứa các trường có thể thay đổi, những trường đó vẫn có thể thay đổi. Điều này đúng với tất cả các cấu trúc dữ liệu lồng nhau trong Python (xem video này để biết thêm thông tin)

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
17

Mặc dù cả

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
31 và
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
32 đều không thay đổi, nhưng danh sách chứa
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
33 thì không. Do đó, bạn vẫn có thể thay đổi các thẻ trong bộ bài

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
18

Để tránh điều này, hãy đảm bảo rằng tất cả các trường của lớp dữ liệu không thay đổi đều sử dụng các loại không thay đổi (nhưng hãy nhớ rằng các loại không được thực thi trong thời gian chạy).

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
32 nên được triển khai bằng cách sử dụng Tuple thay vì danh sách

Di sản

Bạn có thể phân lớp các lớp dữ liệu khá tự do. Ví dụ: chúng tôi sẽ mở rộng ví dụ

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
00 của mình với trường
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
36 và sử dụng trường này để ghi chữ hoa

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
19

Trong ví dụ đơn giản này, mọi thứ hoạt động trơn tru

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
0

Trường

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
36 của
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
38 được thêm vào sau ba trường ban đầu trong
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
00. Mọi thứ trở nên phức tạp hơn một chút nếu bất kỳ trường nào trong lớp cơ sở có giá trị mặc định

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
1

Mã này sẽ ngay lập tức gặp sự cố với một

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
40 phàn nàn rằng "đối số không mặc định 'quốc gia' theo sau đối số mặc định. ” Vấn đề là trường
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
36 mới của chúng tôi không có giá trị mặc định, trong khi trường
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
42 và
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
43 có giá trị mặc định. Lớp dữ liệu sẽ cố gắng viết một phương thức
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
07 với chữ ký sau

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
2

Tuy nhiên, đây không phải là Python hợp lệ. Nếu một tham số có giá trị mặc định thì tất cả các tham số sau cũng phải có giá trị mặc định. Nói cách khác, nếu một trường trong lớp cơ sở có giá trị mặc định, thì tất cả các trường mới được thêm vào trong lớp con cũng phải có giá trị mặc định

Một điều khác cần lưu ý là cách các trường được sắp xếp trong một lớp con. Bắt đầu với lớp cơ sở, các trường được sắp xếp theo thứ tự mà chúng được xác định đầu tiên. Nếu một trường được xác định lại trong một lớp con, thứ tự của nó không thay đổi. Ví dụ: nếu bạn xác định

>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
00 và
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
38 như sau

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
3

Khi đó thứ tự của các trường trong

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
38 vẫn sẽ là
>>> queen_of_hearts = DataClassCard('Q', 'Hearts')
>>> queen_of_hearts.rank
'Q'
>>> queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>> queen_of_hearts == DataClassCard('Q', 'Hearts')
True
13,
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
42,
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
43,
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
36. Tuy nhiên, giá trị mặc định của
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
43 sẽ là
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
53

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
4

Loại bỏ các quảng cáo

Tối ưu hóa các lớp dữ liệu

Tôi sẽ kết thúc hướng dẫn này bằng một vài từ về máy đánh bạc. Các khe cắm có thể được sử dụng để làm cho các lớp nhanh hơn và sử dụng ít bộ nhớ hơn. Các lớp dữ liệu không có cú pháp rõ ràng để làm việc với các vị trí, nhưng cách thông thường để tạo các vị trí cũng phù hợp với các lớp dữ liệu. (Họ thực sự chỉ là những lớp học thông thường. )

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
5

Về cơ bản, các vị trí được xác định bằng cách sử dụng

class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
54 để liệt kê các biến trên một lớp. Các biến hoặc thuộc tính không có trong
class RegularCard:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
54 có thể không được xác định. Hơn nữa, một lớp vị trí có thể không có giá trị mặc định

Lợi ích của việc thêm các hạn chế như vậy là có thể thực hiện một số tối ưu hóa nhất định. Chẳng hạn, các lớp vị trí chiếm ít bộ nhớ hơn, có thể được đo bằng Pympler

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
6

Tương tự, các lớp vị trí thường hoạt động nhanh hơn với. Ví dụ sau đo tốc độ truy cập thuộc tính trên lớp dữ liệu vị trí và lớp dữ liệu thông thường bằng cách sử dụng timeit từ thư viện chuẩn

>>>

>>> queen_of_hearts_tuple = ('Q', 'Hearts')
>>> queen_of_hearts_dict = {'rank': 'Q', 'suit': 'Hearts'}
7

Trong ví dụ cụ thể này, lớp vị trí nhanh hơn khoảng 35%

Kết luận và đọc thêm

Các lớp dữ liệu là một trong những tính năng mới của Python 3. 7. Với các lớp dữ liệu, bạn không cần phải viết mã soạn sẵn để khởi tạo, biểu diễn và so sánh phù hợp cho các đối tượng của mình

Bạn đã thấy cách định nghĩa các lớp dữ liệu của riêng mình, cũng như

  • Cách thêm giá trị mặc định vào các trường trong lớp dữ liệu của bạn
  • Cách tùy chỉnh thứ tự của các đối tượng lớp dữ liệu
  • Cách làm việc với các lớp dữ liệu bất biến
  • Cách kế thừa hoạt động cho các lớp dữ liệu

Nếu bạn muốn đi sâu vào tất cả các chi tiết của các lớp dữ liệu, hãy xem PEP 557 cũng như các cuộc thảo luận trong repo GitHub gốc

Ngoài ra, buổi nói chuyện về PyCon 2018 của Raymond Hettinger Dataclasses. Trình tạo mã để kết thúc tất cả các trình tạo mã rất đáng xem

Nếu bạn chưa có Python 3. 7, cũng có một backport lớp dữ liệu cho Python 3. 6. Và bây giờ, hãy tiếp tục và viết ít mã hơn

Đánh dấu là đã hoàn thành

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Sử dụng các lớp dữ liệu trong Python

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Lớp dữ liệu chung của Python

Gửi cho tôi thủ thuật Python »

Giới thiệu về Geir Arne Hjelle

Lớp dữ liệu chung của Python
Lớp dữ liệu chung của Python

Geir Arne là một Pythonista cuồng nhiệt và là thành viên của nhóm hướng dẫn Real Python

» Thông tin thêm về Geir Arne


Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Lớp dữ liệu chung của Python

Aldren

Lớp dữ liệu chung của Python

Đan

Lớp dữ liệu chung của Python

Joanna

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Lớp dữ liệu chung của Python

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bậc thầy Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

@dataclass nghĩa là gì trong Python?

Lớp dữ liệu là lớp thường chứa chủ yếu là dữ liệu, mặc dù thực sự không có bất kỳ hạn chế nào . Nó được tạo bằng trình trang trí @dataclass mới, như sau. từ lớp dữ liệu nhập lớp dữ liệu @dataclass lớp DataClassCard. cấp. phù hợp với str. str.

Tôi có nên luôn sử dụng Dataclass Python không?

Nếu bạn không phải hỗ trợ ứng dụng hoặc thư viện của mình trên các phiên bản Python cũ hơn, thì các lớp dữ liệu có vẻ phù hợp khi thích hợp . Nếu bạn làm như vậy, bạn sẽ phải sống mà không có chúng hoặc nhập lại mô-đun.

Dataclass có thể kế thừa từ một lớp bình thường không?

Khi một DataClass kế thừa một lớp thông thường , __init__() từ siêu lớp sẽ bị ghi đè trong lớp con. tác giả trong GfgArticle ghi đè tương tự trong Article – Là khái niệm cơ bản về thừa kế, giá trị cho phép gán của nó trước tiên được tìm trong lớp con và theo dõi cây trong siêu lớp.

Khi nào tôi nên sử dụng Dataclass trong Python?

Sử dụng lớp dữ liệu, bạn có thể tạo các đối tượng chỉ đọc . Tất cả những gì bạn phải làm là đặt đối số cố định thành True bên trong trình trang trí @dataclass. Khi bạn thực hiện việc này, bạn sẽ ngăn không cho bất kỳ ai sửa đổi giá trị của các thuộc tính sau khi đối tượng được khởi tạo.