您的位置:首頁技術文章
文章詳情頁

Python如何定義接口和抽象類

瀏覽:3日期:2022-07-16 08:38:45

問題

你想定義一個接口或抽象類,并且通過執行類型檢查來確保子類實現了某些特定的方法

解決方案

使用 abc 模塊可以很輕松的定義抽象基類:

from abc import ABCMeta, abstractmethodclass IStream(metaclass=ABCMeta): @abstractmethod def read(self, maxbytes=-1): pass @abstractmethod def write(self, data): pass

抽象類的一個特點是它不能直接被實例化,比如你想像下面這樣做是不行的:

a = IStream() # TypeError: Can’t instantiate abstract class# IStream with abstract methods read, write

抽象類的目的就是讓別的類繼承它并實現特定的抽象方法:

class SocketStream(IStream): def read(self, maxbytes=-1): pass def write(self, data): pass

抽象基類的一個主要用途是在代碼中檢查某些類是否為特定類型,實現了特定接口:

def serialize(obj, stream): if not isinstance(stream, IStream): raise TypeError(’Expected an IStream’) pass

除了繼承這種方式外,還可以通過注冊方式來讓某個類實現抽象基類:

import io# Register the built-in I/O classes as supporting our interfaceIStream.register(io.IOBase)# Open a normal file and type checkf = open(’foo.txt’)isinstance(f, IStream) # Returns True

@abstractmethod 還能注解靜態方法、類方法和 properties 。 你只需保證這個注解緊靠在函數定義前即可:

class A(metaclass=ABCMeta): @property @abstractmethod def name(self): pass @name.setter @abstractmethod def name(self, value): pass @classmethod @abstractmethod def method1(cls): pass @staticmethod @abstractmethod def method2(): pass

討論

標準庫中有很多用到抽象基類的地方。collections 模塊定義了很多跟容器和迭代器(序列、映射、集合等)有關的抽象基類。 numbers 庫定義了跟數字對象(整數、浮點數、有理數等)有關的基類。io 庫定義了很多跟I/O操作相關的基類。

你可以使用預定義的抽象類來執行更通用的類型檢查,例如:

import collections# Check if x is a sequenceif isinstance(x, collections.Sequence):...# Check if x is iterableif isinstance(x, collections.Iterable):...# Check if x has a sizeif isinstance(x, collections.Sized):...# Check if x is a mappingif isinstance(x, collections.Mapping):

盡管ABCs可以讓我們很方便的做類型檢查,但是我們在代碼中最好不要過多的使用它。 因為Python的本質是一門動態編程語言,其目的就是給你更多靈活性, 強制類型檢查或讓你代碼變得更復雜,這樣做無異于舍本求末。

以上就是Python如何定義接口和抽象類的詳細內容,更多關于Python定義接口和抽象類的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
国产综合久久一区二区三区