Giao diện trong Python rất tiếc

Ngôn ngữ lập trình Python không bao gồm hỗ trợ trực tiếp cho các giao diện giống như các ngôn ngữ lập trình hướng đối tượng khác. Tuy nhiên, có thể xây dựng chức năng tương tự trong Python chỉ với một chút công việc. Để biết ngữ cảnh đầy đủ, hãy xem từ Real Python. Nó bao gồm một cuộc thảo luận sâu hơn nhiều về các khía cạnh khác nhau của mã này và lý do tại sao chúng tôi sử dụng nó

Giao diện Python chính thức

Để tạo một giao diện trong Python, chúng ta sẽ tạo một lớp bao gồm một số phần tử khác nhau. Hãy xem một ví dụ về giao diện

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
6 mà chúng ta có thể tạo, giao diện này có thể được sử dụng cho nhiều loại bộ sưu tập như danh sách, ngăn xếp và hàng đợi

import abc
from typing import List


class IMyCollection[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyCollection:
            attrs: List[str] = ['size', 'empty']
            callables: List[str] = ['add', 'remove', 'get', 'contains']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @property
    @abc.abstractmethod
    def size[self] -> int:
        raise NotImplementedError
        
    @property
    @abc.abstractmethod
    def empty[self] -> bool:
        raise NotImplementedError
        
    @abc.abstractmethod
    def add[self, o: object] -> bool:
        raise NotImplementedError
        
    @abc.abstractmethod
    def remove[self, i: int] -> bool:
        raise NotImplementedError
        
    @abc.abstractmethod
    def get[self, i: int] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def contains[self, o: object] -> bool:
        raise NotImplementedError

Mã này bao gồm khá nhiều yếu tố thú vị. Hãy xem xét từng người trong số họ

  • Đầu tiên, chúng tôi nhập thư viện
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    7, như bạn có thể nhớ lại là thư viện cho các lớp cơ sở trừu tượng
  • Chúng tôi cũng đang nhập lớp
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    8 từ thư viện
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    0 để hỗ trợ kiểm tra loại
  • Trong định nghĩa lớp cho lớp
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    1 của chúng tôi, chúng tôi liệt kê lớp
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    2 là siêu dữ liệu cho lớp này. Điều này cho phép Python thực hiện một số phân tích trên chính mã đó. Bạn có thể đọc thêm về Python Metaclasses từ Real Python
  • Bên trong lớp, chúng tôi đang ghi đè một phương thức của lớp,
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    3. Phương thức này được sử dụng để xác định xem một lớp nhất định có thực hiện đúng giao diện này không. Khi chúng ta sử dụng phương thức Python
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    4, nó sẽ gọi phương thức này đằng sau hậu trường. Xem bên dưới để thảo luận về những gì phương pháp đó làm
  • Sau đó, mỗi thuộc tính và phương thức trong giao diện được triển khai dưới dạng phương thức trừu tượng bằng cách sử dụng trình trang trí
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    5. Các phương thức đó chỉ đơn giản là tạo ra một
    import abc
    from typing import List
    
    
    class IMyStack[metaclass=abc.ABCMeta]:
    
        @classmethod
        def __subclasshook__[cls, subclass: type] -> bool:
            if cls is IMyStack:
                attrs: List[str] = []
                callables: List[str] = ['push', 'pop', 'peek']
                ret: bool = True
                for attr in attrs:
                    ret = ret and [hasattr[subclass, attr] 
                                   and isinstance[getattr[subclass, attr], property]]
                for call in callables:
                    ret = ret and [hasattr[subclass, call] 
                                   and callable[getattr[subclass, call]]]
                return ret
            else:
                return NotImplemented
            
        @abc.abstractmethod
        def push[self, o: object] -> None:
            raise NotImplementedError
            
        @abc.abstractmethod
        def pop[self] -> object:
            raise NotImplementedError
            
        @abc.abstractmethod
        def peek[self] -> object:
            raise NotImplementedError
    
    6, bắt buộc bất kỳ lớp nào triển khai giao diện này cung cấp các triển khai cho từng phương thức này. Nếu không, trình thông dịch Python sẽ báo lỗi đó cho chúng ta

Phương pháp subclasshook

Phương thức

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
3 trong lớp giao diện của chúng tôi ở trên thực hiện một tác vụ thường được xử lý tự động cho chúng tôi trong nhiều ngôn ngữ lập trình khác. Tuy nhiên, vì Python được nhập động, chúng tôi sẽ muốn ghi đè phương thức này để giúp chúng tôi xác định xem có đối tượng đã cho nào tương thích với giao diện này không. Phương pháp này sử dụng một vài phương pháp siêu lập trình trong Python

Trước tiên, chúng ta phải kiểm tra và đảm bảo lớp mà phương thức này đang được gọi,

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
8, là lớp giao diện của chúng ta. Nếu không, chúng tôi sẽ cần trả về
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
9 để Python tiếp tục sử dụng các phương thức thông thường để kiểm tra loại. ^[Xem https. // stackoverflow. com/câu hỏi/40764347/python-subclasscheck-subclasshook để biết chi tiết]

Sau đó, chúng tôi thấy hai danh sách các chuỗi có tên là

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
10 và
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
11. Danh sách
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
10 là danh sách tất cả các thuộc tính Python nên là một phần của giao diện của chúng ta - trong trường hợp này, nó phải có thuộc tính
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
13 và
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
14. Danh sách
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
11 là danh sách tất cả các phương thức có thể gọi được ngoài các thuộc tính. Vì vậy, lớp
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
1 của chúng ta sẽ bao gồm các phương thức
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
17,
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
18,
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
19 và
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
10

Bên dưới đó, chúng tôi tìm thấy hai vòng lặp

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
11. Vòng lặp đầu tiên sẽ kiểm tra xem lớp đã cho, được lưu trữ trong
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
12, có chứa các thuộc tính cho từng mục được liệt kê trong danh sách
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
10 không. Trước tiên, nó sử dụng phương pháp lập trình siêu dữ liệu
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
14 để xác định rằng lớp có một thuộc tính có tên đó, sau đó sử dụng phương thức
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
15 cùng với phương pháp
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
16 để đảm bảo rằng thuộc tính đó là một thể hiện của thuộc tính Python

Tương tự, vòng lặp

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
11 thứ hai thực hiện quy trình tương tự cho các phương thức được liệt kê trong danh sách
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
11. Thay vì sử dụng
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
15, chúng tôi sử dụng phương thức
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
10 để đảm bảo rằng thuộc tính là một phương thức có thể gọi được

Phương pháp này hơi phức tạp, nhưng nó là một cái nhìn tốt về cách trình biên dịch hoặc trình thông dịch cho các ngôn ngữ hướng đối tượng khác thực hiện nhiệm vụ đảm bảo một lớp thực hiện đúng một giao diện. Để sử dụng, chúng tôi chỉ cần sao chép-dán mã này vào bất kỳ giao diện nào chúng tôi tạo, sau đó cập nhật danh sách

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
10 và
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
11 nếu cần

Giao diện thứ hai

Hãy xem xét một giao diện Python chính thức hơn, lần này là một ngăn xếp

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError

Đây là một giao diện đơn giản hơn, chỉ định nghĩa các phương thức cho

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
13,
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
14 và
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
15

Triển khai giao diện

Khi chúng tôi đã tạo một giao diện, chúng tôi có thể tạo một lớp thực hiện giao diện đó. Bất kỳ lớp nào triển khai giao diện phải cung cấp triển khai cho tất cả các phương thức được xác định trong giao diện

Ví dụ: chúng ta có thể tạo một lớp

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
16 triển khai giao diện
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
1 được xác định ở trên, như trong ví dụ này

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
1

Lưu ý rằng chúng tôi bao gồm lớp giao diện trong dấu ngoặc đơn như một phần của khai báo lớp, điều này sẽ cho Python biết giao diện mà chúng tôi đang triển khai trong lớp này. Sau đó, trong lớp, chúng tôi bao gồm các triển khai cho từng phương thức được xác định trong giao diện

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
1. Những cách triển khai đó đơn giản và đầy lỗi, nhưng chúng cho chúng ta ý tưởng hay về việc triển khai một giao diện có thể trông như thế nào. Chúng tôi cũng có thể bao gồm nhiều thuộc tính và hàm tạo hơn, cũng như các phương thức bổ sung nếu cần

Đa thừa kế

Python cũng cho phép một lớp triển khai nhiều hơn một giao diện. Đây là một kiểu thừa kế đặc biệt được gọi là đa thừa kế. Bất kỳ lớp nào triển khai nhiều giao diện phải cung cấp cách triển khai cho mọi phương thức được xác định trong mỗi giao diện mà nó triển khai

Ví dụ: chúng ta có thể tạo một lớp

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
19 đặc biệt triển khai cả giao diện
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
1 và
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
41 mà chúng ta đã xác định ở trên

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
1

Để triển khai nhiều giao diện, chúng ta chỉ cần liệt kê chúng bên trong dấu ngoặc đơn như một phần của định nghĩa lớp, được phân tách bằng dấu phẩy

Giao diện như các loại

Cuối cùng, nhớ lại từ trang trước rằng chúng ta có thể coi bất kỳ giao diện nào là một kiểu dữ liệu, vì vậy chúng ta có thể coi các lớp triển khai cùng một giao diện theo cùng một cách. Đây là một ví dụ

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
1

Tuy nhiên, điều quan trọng cần nhớ là, vì phần tử thứ hai trong mảng

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
42 là một thể hiện của lớp
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
19, nên chúng ta cũng có thể truy cập trực tiếp các phương thức
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
13 và
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
14. Điều này là do Python sử dụng kiểu gõ động và kiểu gõ vịt, vì vậy miễn là đối tượng hỗ trợ các phương thức đó, chúng ta có thể sử dụng chúng. Nói cách khác, nếu đối tượng có thể nhận được những tin nhắn đó, chúng ta có thể chuyển chúng cho đối tượng

Có hai phương thức đặc biệt mà chúng ta có thể sử dụng để xác định loại đối tượng trong Python

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
4

Phương thức

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
15 trong Python được sử dụng để xác định xem một đối tượng có phải là một thể hiện của một lớp nhất định hay không

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
3

Phương thức

import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
4 được sử dụng để xác định xem một đối tượng có phải là lớp con của một lớp nhất định hay không. Vì chúng ta đang tạo một giao diện chính thức trong Python và ghi đè phương thức
import abc
from typing import List


class IMyStack[metaclass=abc.ABCMeta]:

    @classmethod
    def __subclasshook__[cls, subclass: type] -> bool:
        if cls is IMyStack:
            attrs: List[str] = []
            callables: List[str] = ['push', 'pop', 'peek']
            ret: bool = True
            for attr in attrs:
                ret = ret and [hasattr[subclass, attr] 
                               and isinstance[getattr[subclass, attr], property]]
            for call in callables:
                ret = ret and [hasattr[subclass, call] 
                               and callable[getattr[subclass, call]]]
            return ret
        else:
            return NotImplemented
        
    @abc.abstractmethod
    def push[self, o: object] -> None:
        raise NotImplementedError
        
    @abc.abstractmethod
    def pop[self] -> object:
        raise NotImplementedError
        
    @abc.abstractmethod
    def peek[self] -> object:
        raise NotImplementedError
3, điều này sẽ xác định xem đối tượng có bao gồm đúng tất cả các thuộc tính và phương thức bắt buộc được xác định bởi giao diện hay không

Giao diện trong OOP Python là gì?

Tổng quan về giao diện Python . Giống như các lớp, các giao diện định nghĩa các phương thức. Không giống như các lớp, các phương thức này là trừu tượng. Một phương thức trừu tượng là một phương thức mà giao diện chỉ định nghĩa. Nó không thực hiện các phương pháp. acts as a blueprint for designing classes. Like classes, interfaces define methods. Unlike classes, these methods are abstract. An abstract method is one that the interface simply defines. It doesn't implement the methods.

Các giao diện được sử dụng để làm gì trong OOP?

Giao diện cho phép bạn chỉ định những phương thức mà một lớp nên triển khai . Các giao diện giúp dễ dàng sử dụng nhiều lớp khác nhau theo cùng một cách. Khi một hoặc nhiều lớp sử dụng cùng một giao diện, nó được gọi là "đa hình".

Có một giao diện trong Python?

Thật không may, Python không có giao diện , hoặc ít nhất, không được tích hợp hoàn toàn vào ngôn ngữ. Nhập lớp cơ sở trừu tượng của Python, hoặc dễ thương là ABC. Về mặt chức năng, các lớp cơ sở trừu tượng cho phép bạn định nghĩa một lớp với các phương thức trừu tượng mà tất cả các lớp con phải triển khai để được khởi tạo.

Tại sao nên sử dụng giao diện trong Python?

Giới thiệu về Giao diện trong Python. Một giao diện hoạt động như một khuôn mẫu để thiết kế các lớp. Các giao diện cũng định nghĩa các phương thức giống như các lớp, nhưng các phương thức trừu tượng, trong khi lớp chứa các phương thức không trừu tượng. Các phương thức trừu tượng là những phương thức không có triển khai hoặc không có phần thân

Chủ Đề