Gọi lớp bên trong một lớp python khác

Chúng tôi có một lớp tên là

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
2, kế thừa từ một lớp khác,
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3 (nằm trong mô-đun
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
4 trong thư viện chuẩn của Python)

from collections import Counter


class FancyCounter(Counter):
    def commonest(self):
        (value1, count1), (value2, count2) = self.most_common(2)
        if count1 == count2:
            raise ValueError("No unique most common value")
        return value1

Cách chúng tôi biết chúng tôi đang kế thừa từ lớp

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3 bởi vì khi chúng tôi định nghĩa
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
2, ngay sau tên lớp, chúng tôi đặt dấu ngoặc đơn và viết
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3 bên trong chúng

Để tạo một lớp kế thừa từ một lớp khác, sau tên lớp bạn sẽ đặt dấu ngoặc đơn và sau đó liệt kê bất kỳ lớp nào mà lớp của bạn kế thừa từ đó

Trong định nghĩa hàm, dấu ngoặc đơn sau tên hàm biểu thị các đối số mà hàm chấp nhận. Trong một định nghĩa lớp, dấu ngoặc đơn sau tên lớp thay vì đại diện cho các lớp được kế thừa từ

Thông thường khi thực hành kế thừa lớp trong Python, chúng ta chỉ kế thừa từ một lớp. Bạn có thể kế thừa từ nhiều lớp (gọi là đa kế thừa), nhưng hơi hiếm. Chúng ta sẽ chỉ thảo luận về kế thừa một lớp ngay bây giờ

Các phương thức được kế thừa từ các lớp cha

Để sử dụng lớp

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
2 của chúng ta, chúng ta có thể gọi nó (giống như bất kỳ lớp nào khác)

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")

Lớp của chúng tôi sẽ chấp nhận một chuỗi khi chúng tôi gọi nó vì lớp

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3 đã triển khai một phương thức
>>> letters
FancyCounter({'e': 3, 'l': 2, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1})
0 (một phương thức khởi tạo)

Lớp của chúng tôi cũng có một phương thức

>>> letters
FancyCounter({'e': 3, 'l': 2, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1})
1 để biểu diễn chuỗi đẹp

>>> letters
FancyCounter({'e': 3, 'l': 2, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1})

Nó thậm chí còn có một loạt các chức năng khác. Ví dụ: nó đã ghi đè điều xảy ra khi bạn sử dụng dấu ngoặc vuông để gán các cặp khóa-giá trị trên các thể hiện của lớp

>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})

Chúng ta có thể gán các cặp khóa-giá trị vì lớp cha của chúng ta,

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3 tạo các đối tượng giống như từ điển (a. k. a. )

Tất cả chức năng đó được kế thừa từ lớp

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3

Thêm chức năng mới trong khi kế thừa

Vì vậy, lớp

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
2 của chúng ta đã kế thừa tất cả các chức năng mà lớp
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3 của chúng ta có nhưng chúng ta cũng đã mở rộng nó bằng cách thêm một phương thức bổ sung,
>>> letters
FancyCounter({'e': 3, 'l': 2, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1})
6, phương thức này sẽ cung cấp cho chúng ta mục phổ biến nhất trong lớp của chúng ta

Khi chúng ta gọi phương thức

>>> letters
FancyCounter({'e': 3, 'l': 2, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1})
6, chúng ta sẽ nhận được chữ cái
>>> letters
FancyCounter({'e': 3, 'l': 2, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1})
8 (xuất hiện ba lần trong chuỗi ban đầu chúng ta đã cung cấp cho đối tượng
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
2 của mình)

>>> letters.commonest()
'e'

Phương thức

>>> letters
FancyCounter({'e': 3, 'l': 2, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1})
6 của chúng ta dựa trên phương thức
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
1, mà chúng ta không định nghĩa nhưng lớp cha của chúng ta,
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3, đã định nghĩa

    def commonest(self):
        (value1, count1), (value2, count2) = self.most_common(2)
        if count1 == count2:
            raise ValueError("No unique most common value")
        return value1

Lớp

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
2 của chúng ta có một phương thức
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
4 bởi vì lớp cha của chúng ta,
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3 đã định nghĩa nó cho chúng ta

Ghi đè các phương thức kế thừa

Nếu chúng ta muốn tùy chỉnh điều gì sẽ xảy ra khi gán cho một cặp khóa-giá trị trong lớp này, chúng ta có thể làm điều đó bằng cách ghi đè phương thức

>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
6. Ví dụ: hãy tạo nó sao cho nếu chúng ta gán một khóa cho một giá trị âm, thay vào đó, nó sẽ gán nó cho
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
7

Trước đây khi chúng tôi chỉ định

>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
8 cho
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
9, chúng tôi muốn nó được đặt thành
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
7 thay vì
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
9 (ở đây là
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
9 vì chúng tôi chưa tùy chỉnh cái này)

>>> letters['l'] = -2
>>> letters['l']
-2

Để tùy chỉnh hành vi này, chúng tôi sẽ tạo một phương thức

>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
6 chấp nhận
>>> letters.commonest()
'e'
4,
>>> letters.commonest()
'e'
5 và
>>> letters.commonest()
'e'
6 vì đó là những gì ______13_______6 được cung cấp bởi Python khi nó được gọi

    def __setitem__(self, key, value):
        value = max(0, value)

Phương pháp

>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
6 ở trên về cơ bản nói. nếu
>>> letters.commonest()
'e'
6 là số âm, hãy đặt nó thành
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
7

Nếu chúng ta ngừng viết

>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
6 vào thời điểm này, nó sẽ không hữu ích lắm. Thực tế là phương pháp
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
6 sẽ chẳng làm được gì cả. nó sẽ không báo lỗi, nhưng nó cũng không thực sự làm gì cả

Để làm điều gì đó hữu ích, chúng ta cần gọi phương thức

>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
6 của lớp cha. Chúng ta có thể gọi phương thức
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
6 của lớp cha bằng cách sử dụng
    def commonest(self):
        (value1, count1), (value2, count2) = self.most_common(2)
        if count1 == count2:
            raise ValueError("No unique most common value")
        return value1
5

    def __setitem__(self, key, value):
        value = max(0, value)
        return super().__setitem__(key, value)

Chúng ta đang gọi

    def commonest(self):
        (value1, count1), (value2, count2) = self.most_common(2)
        if count1 == count2:
            raise ValueError("No unique most common value")
        return value1
6, phương thức này sẽ gọi phương thức
>>> letters['l'] = -2
>>> letters
FancyCounter({'e': 3, 'H': 1, 'o': 1, ' ': 1, 't': 1, 'h': 1, 'r': 1, '!': 1, 'l': -2})
6 trên lớp cha của chúng ta (
>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
3) với
>>> letters.commonest()
'e'
5 và giá trị không âm mới của chúng ta là
>>> letters.commonest()
'e'
6

Đây là triển khai đầy đủ của phiên bản mới này của lớp

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
2 của chúng tôi

from collections import Counter


class FancyCounter(Counter):
    def commonest(self):
        (value1, count1), (value2, count2) = self.most_common(2)
        if count1 == count2:
            raise ValueError("No unique most common value")
        return value1
    def __setitem__(self, key, value):
        value = max(0, value)
        return super().__setitem__(key, value)

Để sử dụng lớp này, chúng ta sẽ gọi nó và truyền lại một chuỗi

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")

Nhưng lần này, nếu chúng ta gán một khóa cho một giá trị âm, chúng ta sẽ thấy rằng nó sẽ được gán cho_______13_______7 thay thế

>>> from fancy_counter import FancyCounter
>>> letters = FancyCounter("Hello there!")
1

Bài tập lớp cho người mới bắt đầu nâng cao

Bạn muốn thực hành thêm với các lớp trong Python?

Lộ trình tập Diving Into Classes bao gồm 6 bài tập dành cho người mới bắt đầu nâng cao. Python Morsels cũng bao gồm hàng chục bài tập khác về các lớp và Python hướng đối tượng.

Bạn có thể gọi một lớp trong một lớp Python không?

Một lớp được định nghĩa trong một lớp khác được gọi là lớp bên trong hoặc lớp lồng nhau . Nếu một đối tượng được tạo bằng cách sử dụng lớp con có nghĩa là lớp bên trong thì đối tượng đó cũng có thể được sử dụng bởi lớp cha hoặc lớp gốc. Một lớp cha có thể có một hoặc nhiều lớp bên trong nhưng thường tránh các lớp bên trong.

__ gọi __ trong lớp Python là gì?

Trong Python, __call__() được dùng để phân giải mã được liên kết với một đối tượng có thể gọi được . Bất kỳ đối tượng nào cũng có thể được chuyển đổi thành đối tượng có thể gọi được chỉ bằng cách viết nó ở định dạng lệnh gọi hàm. Một đối tượng thuộc loại đó gọi phương thức __call__() và thực thi mã được liên kết với nó.

Bạn có thể có các lớp lồng nhau trong Python không?

Một trong những tính năng hữu ích và mạnh mẽ nhất của Python là khả năng lồng các lớp trong các lớp. Một lớp lồng nhau là một lớp được định nghĩa bên trong một lớp khác và kế thừa tất cả các biến và phương thức của lớp cha

Làm cách nào để tạo một thể hiện của một lớp trong một lớp khác trong Python?

Để tạo các thể hiện của một lớp, bạn gọi lớp đó bằng tên lớp và truyền vào bất kỳ đối số nào mà phương thức __init__ của nó chấp nhận .