Bài tập đóng gói Python

Khi viết các lớp, người ta thường cố gắng gói gọn các chi tiết bên trong. Phần này giới thiệu một vài thành ngữ lập trình Python cho điều này bao gồm các biến và thuộc tính riêng tư

Công cộng vs Riêng tư

Một trong những vai trò chính của một lớp là đóng gói dữ liệu và chi tiết triển khai bên trong của một đối tượng. Tuy nhiên, một lớp cũng định nghĩa một giao diện chung mà thế giới bên ngoài phải sử dụng để thao tác với đối tượng. Sự khác biệt giữa các chi tiết triển khai và giao diện công khai là rất quan trọng

Vấn đề

Trong Python, hầu hết mọi thứ về lớp và đối tượng đều mở

  • Bạn có thể dễ dàng kiểm tra bên trong đối tượng
  • Bạn có thể thay đổi mọi thứ theo ý muốn
  • Không có khái niệm mạnh mẽ về kiểm soát truy cập [tôi. e. , thành viên lớp riêng]

Đó là một vấn đề khi bạn đang cố gắng tách biệt các chi tiết của việc triển khai nội bộ

Đóng gói Python

Python dựa vào các quy ước lập trình để chỉ ra mục đích sử dụng của một thứ gì đó. Các quy ước này dựa trên việc đặt tên. Có một thái độ chung rằng lập trình viên phải tuân thủ các quy tắc chứ không phải để ngôn ngữ thực thi chúng.

Thuộc tính riêng tư

Bất kỳ tên thuộc tính nào có đầu

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
1 đều được coi là riêng tư

class Person[object]:
    def __init__[self, name]:
        self._name = 0

Như đã đề cập trước đó, đây chỉ là một phong cách lập trình. Bạn vẫn có thể truy cập và thay đổi nó

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>

Theo nguyên tắc chung, bất kỳ tên nào có đầu ____________1 đều được coi là triển khai nội bộ cho dù đó là tên biến, hàm hay tên mô-đun. Nếu bạn thấy mình trực tiếp sử dụng những tên như vậy, có lẽ bạn đã làm sai điều gì đó. Tìm kiếm chức năng cấp cao hơn

Thuộc tính đơn giản

Hãy xem xét lớp sau

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price

Một tính năng đáng ngạc nhiên là bạn có thể đặt các thuộc tính thành bất kỳ giá trị nào

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>

Bạn có thể nhìn vào đó và nghĩ rằng bạn muốn kiểm tra thêm

s.shares = '50'     # Raise a TypeError, this is a string

Bạn sẽ làm điều này như thế nào?

Thuộc tính được quản lý

Một cách tiếp cận. giới thiệu các phương thức truy cập

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name self.set_shares[shares] self.price = price

    # Function that layers the "get" operation
    def get_shares[self]:
        return self._shares

    # Function that layers the "set" operation
    def set_shares[self, value]:
        if not isinstance[value, int]:
            raise TypeError['Expected an int']
        self._shares = value

Thật tệ là điều này phá vỡ tất cả các mã hiện có của chúng tôi.

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
3 trở thành
class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
4

Của cải

Có một cách tiếp cận thay thế cho mô hình trước đó

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price

    @property
    def shares[self]:
        return self._shares

    @shares.setter
    def shares[self, value]:
        if not isinstance[value, int]:
            raise TypeError['Expected int']
        self._shares = value

Truy cập thuộc tính thông thường hiện kích hoạt các phương thức getter và setter trong

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
5 và
class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
6

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares         # Triggers @property
50
>>> s.shares = 75    # Triggers @shares.setter
>>>

Với mẫu này, không cần thay đổi mã nguồn. Trình thiết lập mới cũng được gọi khi có một phép gán trong lớp, bao gồm cả bên trong phương thức

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
7

class Stock:
    def __init__[self, name, shares, price]:
        ...
        # This assignment calls the setter below
        self.shares = shares
        ...

    ...
    @shares.setter
    def shares[self, value]:
        if not isinstance[value, int]:
            raise TypeError['Expected int']
        self._shares = value

Thường có sự nhầm lẫn giữa tài sản và việc sử dụng tên riêng. Mặc dù thuộc tính bên trong sử dụng tên riêng như

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
8, nhưng phần còn lại của lớp [không phải thuộc tính] có thể tiếp tục sử dụng tên như
class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
9

Các thuộc tính cũng hữu ích cho các thuộc tính dữ liệu được tính toán

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price

    @property
    def cost[self]:
        return self.shares * self.price
    ...

Điều này cho phép bạn loại bỏ các dấu ngoặc thừa, che giấu sự thật rằng đó thực sự là một phương thức

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
0

truy cập thống nhất

Ví dụ cuối cùng cho thấy cách đặt một giao diện thống nhất hơn trên một đối tượng. Nếu bạn không làm điều này, một đối tượng có thể gây nhầm lẫn khi sử dụng

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
1

Tại sao

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
0 được yêu cầu cho chi phí, nhưng không phải cho cổ phiếu?

Cú pháp trang trí

Cú pháp

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
1 được gọi là *decoration". Nó chỉ định một công cụ sửa đổi được áp dụng cho định nghĩa hàm ngay sau đó

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
2

Thông tin chi tiết được đưa ra trong Phần 7

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
2 Thuộc tính

Bạn có thể hạn chế tập hợp các tên thuộc tính

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
3

Nó sẽ gây ra lỗi cho các thuộc tính khác

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
4

Mặc dù điều này ngăn ngừa lỗi và hạn chế sử dụng các đối tượng, nhưng nó thực sự được sử dụng cho hiệu suất và giúp Python sử dụng bộ nhớ hiệu quả hơn

Nhận xét cuối cùng về đóng gói

Đừng quá nhiệt tình với các thuộc tính, thuộc tính, vị trí riêng tư, v.v. Chúng phục vụ một mục đích cụ thể và bạn có thể thấy chúng khi đọc mã Python khác. Tuy nhiên, chúng không cần thiết cho hầu hết các mã hàng ngày

bài tập

bài tập 5. 6. Thuộc tính đơn giản

Thuộc tính là một cách hữu ích để thêm "thuộc tính được tính" vào một đối tượng. Trong

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
3, bạn đã tạo một đối tượng
>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
4. Lưu ý rằng trên đối tượng của bạn có một chút mâu thuẫn về cách các loại dữ liệu khác nhau được trích xuất

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
5

Cụ thể, hãy lưu ý cách bạn phải thêm dấu [] vào

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
5 vì đó là một phương thức

Bạn có thể loại bỏ phần thừa [] trên

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
6 nếu bạn biến nó thành tài sản. Lấy lớp
>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
4 của bạn và sửa đổi nó để tính toán chi phí hoạt động như thế này

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
6

Hãy thử gọi

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
8 như một hàm và nhận thấy rằng nó không hoạt động khi mà
>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
5 đã được định nghĩa là một thuộc tính

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
7

Thực hiện thay đổi này có thể sẽ phá vỡ chương trình

s.shares = '50'     # Raise a TypeError, this is a string
0 trước đó của bạn. Bạn có thể cần quay lại và loại bỏ
>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
0 trên phương pháp
>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
6

bài tập 5. 7. Thuộc tính và Setters

Sửa đổi thuộc tính

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
9 để giá trị được lưu trữ trong một thuộc tính riêng tư và một cặp hàm thuộc tính được sử dụng để đảm bảo rằng nó luôn được đặt thành một giá trị nguyên. Đây là một ví dụ về hành vi dự kiến

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
8

bài tập 5. 8. Thêm vị trí

Sửa đổi lớp

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
4 để nó có thuộc tính
>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
2. Sau đó, xác minh rằng không thể thêm các thuộc tính mới

>>> p = Person['Guido']
>>> p._name
'Guido'
>>> p._name = 'Dave'
>>>
9

Khi bạn sử dụng

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
2, Python sẽ sử dụng cách biểu diễn đối tượng bên trong hiệu quả hơn. Điều gì xảy ra nếu bạn cố gắng kiểm tra từ điển cơ bản của
s.shares = '50'     # Raise a TypeError, this is a string
7 ở trên?

class Stock:
    def __init__[self, name, shares, price]:
        self.name = name
        self.shares = shares
        self.price = price
0

Cần lưu ý rằng

>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
2 được sử dụng phổ biến nhất để tối ưu hóa trên các lớp đóng vai trò là cấu trúc dữ liệu. Sử dụng khe cắm sẽ làm cho các chương trình như vậy sử dụng ít bộ nhớ hơn và chạy nhanh hơn một chút. Tuy nhiên, có lẽ bạn nên tránh
>>> s = Stock['IBM', 50, 91.1]
>>> s.shares = 100
>>> s.shares = "hundred"
>>> s.shares = [1, 0, 0]
>>>
2 trên hầu hết các lớp học khác

đóng gói trong Python với ví dụ là gì?

Đóng gói trong Python mô tả khái niệm về gói dữ liệu và phương thức trong một đơn vị . Vì vậy, ví dụ, khi bạn tạo một lớp, điều đó có nghĩa là bạn đang thực hiện đóng gói. Một lớp là một ví dụ về đóng gói vì nó liên kết tất cả các thành viên dữ liệu [biến thể hiện] và các phương thức thành một đơn vị.

Tôi có thể thực hành OOP trong Python ở đâu?

Bài tập lập trình hướng đối tượng Python [OOP]. Bài tập về lớp và đối tượng .
Tạo lớp và đối tượng
Các biến thể hiện và Phương thức và các thuộc tính cấp Lớp
Hệ thống mô hình với kế thừa lớp i. e. , kế thừa từ các lớp khác
Lớp cha và lớp con

Các ví dụ thực tế về đóng gói là gì?

Hãy xem xét ví dụ thời gian thực bên dưới. đóng gói. Là người lái xe, bạn biết cách khởi động ô tô bằng cách nhấn nút khởi động và thông tin chi tiết bên trong về thao tác khởi động được ẩn khỏi bạn . Vì vậy, toàn bộ quá trình bắt đầu được ẩn khỏi bạn, nếu không, chúng tôi có thể cho biết hoạt động bắt đầu được gói gọn từ bạn.

Tại sao Python không hỗ trợ đóng gói?

Python không hỗ trợ đóng gói mạnh, đây chỉ là một trong nhiều tính năng liên quan đến thuật ngữ "hướng đối tượng". Câu trả lời đơn giản là triết học. Guido không thích che giấu mọi thứ và nhiều người trong cộng đồng Python đồng ý với anh ấy.

Chủ Đề