返回顶部
首页 > 资讯 > 后端开发 > Python >Python抽象基类的定义与使用方法
  • 308
分享到

Python抽象基类的定义与使用方法

2024-04-02 19:04:59 308人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录1、定义抽象基类的子类2、标准库中的抽象基类3、定义抽象基类4、再看白鹅类型前言: 我们写python基本不需要自己创建抽象基类,而是通过鸭子类型来解决大部分问题。《流畅的Pyt

前言:

我们写python基本不需要自己创建抽象基类,而是通过鸭子类型来解决大部分问题。《流畅的Python》作者使用了15年Python,但只在项目中创建过一个抽象基类。我们更多时候是创建现有抽象基类的子类,或者使用现有的抽象基类注册。本文的意义在于,了解抽象基类的定义与使用,可以帮助我们理解抽象基类是如何实现的,为我们以后学习后端语言(比如Javagolang)打下基础。毕竟抽象基类是编程语言通用设计。

1、定义抽象基类的子类

先回顾下什么是抽象基类:Python的抽象基类是指必须让继承它的子类去实现它所要求的抽象方法的类。

如下代码定义了抽象基类collections.MutableSequence的子类:


import collections 
 
Card = collections.namedtuple('Card', ['rank', 'suit']) 
 
class FrenchDeck2(collections.MutableSequence): 
    ranks = [str(n) for n in range(2, 11)] + list('JQKA') 
    suits = 'spades diamonds clubs hearts'.split() 
 
    def __init__(self): 
        self._cards = [Card(rank, suit) for suit in self.suits 
                                        for rank in self.ranks] 
 
    def __len__(self): 
        return len(self._cards) 
 
    def __getitem__(self, position): 
        return self._cards[position] 
 
    def __setitem__(self, position, value):  # <1> 
        self._cards[position] = value 
 
    def __delitem__(self, position):  # <2> 
        del self._cards[position] 
 
    def insert(self, position, value):  # <3> 
        self._cards.insert(position, value) 


通过抽象基类collections.MutableSequence源码:

可以发现,它有三个抽象方法__setitem__ __delitem__ insert,所以FrenchDeck2类必须实现它们。而对于其他非抽象方法比如appendextendpop等,则可以直接继承无需实现。

注意:Python只会在运行时实例化FrenchDeck2类时真正检查抽象方法的实现,如果未实现会抛出TypeError异常,提示Can't instantiate abstract class之类的。

2、标准库中的抽象基类

为了知道哪些抽象基类可以使用,我们可以看看标准库。

collections.abc

collections.abc的抽象基类如下图所示:

Iterable、Container、Sized

这三个抽象基类是最基础的类,各个集合都继承了这三个抽象基类。

  • Itearble通过__iter__方法支持迭代
  • Container通过__contains__方法支持in运算符
  • Sized通过__len__方法支持len()函数

Sequence、Mapping、Set

不可变集合类型,各自都有可变的子类。

MappingView

.items().keys() .values()返回的对象分别是ItemsViewKeysViewValuesView的实例。

Callable、Hashable

为内置函数isinstance提供支持,判断对象能不能调用或散列。

Iterator

迭代器。

numbers

numbers的抽象基类有以下几种:

  • Number
  • Complex
  • Real
  • Rational
  • Integral

这叫做数字塔,顶部是超类,底部是子类。比如使用isinstance(x, numbers.Integral)检查一个数是不是整数,这样代码就能接受intbool(int的子类),再比如使用isinstance(x, numbers.Real)检查浮点数,这样代码就能接受boolintfloatfractions.Fraction

3、定义抽象基类

抽象基类的示例代码如下:


# BEGIN TOMBOLA_ABC 
 
import abc 
 
class Tombola(abc.ABC):  # <1> 
 
    @abc.abstractmethod 
    def load(self, iterable):  # <2> 
        """Add items from an iterable.""" 
 
    @abc.abstractmethod 
    def pick(self):  # <3> 
        """Remove item at random, returning it. 
        This method should raise `LookupError` when the instance is empty. 
        """ 
 
    def loaded(self):  # <4> 
        """Return `True` if there's at least 1 item, `False` otherwise.""" 
        return bool(self.inspect())  # <5> 
 
 
    def inspect(self): 
        """Return a sorted tuple with the items currently inside.""" 
        items = [] 
        while True:  # <6> 
            try: 
                items.append(self.pick()) 
            except LookupError: 
                break 
        self.load(items)  # <7> 
        return tuple(sorted(items)) 
 
 
# END TOMBOLA_ABC 

要点:

  • 继承abc.ABC
  • 使用@abc.abstractmethod装饰器标记抽象方法
  • 抽象基类也可以包含普通方法
  • 抽象基类的子类必须覆盖抽象方法(普通方法可以不覆盖),可以使用super()函数调用抽象方法,为它添加功能,而不是从头开始实现

4、再看白鹅类型

白鹅类型的定义有一点难以理解,如果理解了虚拟子类,就能加快理解白鹅类型。虚拟子类并不是抽象基类的真正子类,而是注册到抽象基类上的子类,这样Python就不会做强制检查了。

注册的方式有两种:

python3.3以前只能使用register方法,比如collections.abc模块的源码中,把内置类型tuplestrrangememoryview注册为Sequence的虚拟子类:


Sequence.register(tuple) 
Sequence.register(str) 
Sequence.register(range) 
Sequence.register(memoryview) 


  • register装饰器

TomboList注册为Tombola的虚拟子类:


@Tombola.register 
class TomboList(list): 
    ... 


白鹅类型和鸭子类型是Python的动态特性,它们的共同点是,只要长的像,Python就不会做强制检查,鸭子类型是针对普通类的子类而言的,白鹅类型是针对抽象基类的虚拟子类而言的。

参考资料:

《流畅的Python》第11章 接口:从协议到抽象基类

到此这篇关于Python抽象基类的定义与使用方法的文章就介绍到这了,更多相关Python抽象基类的定义与使用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python抽象基类的定义与使用方法

本文链接: https://lsjlt.com/news/154766.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python抽象基类的定义与使用方法
    目录1、定义抽象基类的子类2、标准库中的抽象基类3、定义抽象基类4、再看白鹅类型前言: 我们写Python基本不需要自己创建抽象基类,而是通过鸭子类型来解决大部分问题。《流畅的Pyt...
    99+
    2024-04-02
  • 在Python中定义和使用抽象类的方法
    像java一样python也可以定义一个抽象类。 在讲抽象类之前,先说下抽象方法的实现。 抽象方法是基类中定义的方法,但却没有任何实现。在java中,可以把方法申明成一个接口。而在python中实现一个抽象...
    99+
    2022-06-04
    定义 方法 抽象类
  • 在Python中定义和使用 抽象类及抽象
    原文链接:http://www.jb51.net/article/87710.htm 本文根据自己的理解和思考,对原文略有改动。。。 Python中我们可以使用abc模块来构建抽象类。在讲抽象类之前,先说下抽象方法的实现。 抽象方法是基类...
    99+
    2023-01-31
    抽象 定义 抽象类
  • python抽象类的使用方法
    这篇文章主要介绍了python抽象类的使用方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、问题描述主要使用场景是这样的比如京东上买东西,买完东西后需要支付,京东可以使用...
    99+
    2023-06-08
  • Java抽象类与接口怎么定义使用
    这篇文章主要介绍“Java抽象类与接口怎么定义使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java抽象类与接口怎么定义使用”文章能帮助大家解决问题。1.对象的比较两个对象要进行比较之前,我们首...
    99+
    2023-06-30
  • c++抽象类怎么定义及使用
    C++中的抽象类是指含有纯虚函数的类,它不能被实例化,只能被继承。抽象类用于定义一个接口,具体的实现由派生类完成。抽象类的定义通常包...
    99+
    2023-10-12
    c++
  • 详解JavaSE中抽象类与接口的定义及使用
    目录一、抽象类1、抽象类定义2、抽象方法二、接口1、接口定义2、类实现接口3、接口与多态联合4、extends和implements5、接口在开发当中的作用6、is has like...
    99+
    2024-04-02
  • java中的抽象类和接口定义与用法详解
    目录一、抽象类1.什么叫抽象类?2.抽象类的特点:3.成员特点:二、接口1.接口是什么?2.接口的特点3.接口的组成成员4.类与抽象的关系:5.抽象类与接口的区别:一、抽象类...
    99+
    2024-04-02
  • JavaSE中抽象类与接口怎么定义及使用
    这篇文章主要介绍“JavaSE中抽象类与接口怎么定义及使用”,在日常操作中,相信很多人在JavaSE中抽象类与接口怎么定义及使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JavaSE中抽象类与接口怎么定义...
    99+
    2023-07-02
  • JAVA抽象类和抽象方法怎么使用
    在Java中,抽象类是用来定义一组相关类的共同特征和行为的。抽象类不能被实例化,只能被继承。要定义一个抽象类,需要在类的声明前加上关...
    99+
    2023-08-17
    JAVA
  • php能定义抽象方法吗
    本教程操作环境:windows7系统、PHP7.1版、DELL G3电脑php能定义抽象方法。在面向对象语言中,一个类可以有一个或多个子类,而每个类都应该至少有一个公有方法作为外部代码访问它的入口。抽象类和抽象方法是在 PHP5 中引入的一...
    99+
    2015-12-08
    php 抽象方法
  • Python实现抽象基类的3三种方法
    Python的抽象基类类似于Java、C++等面向对象语言中的接口的概念。抽象基类提供了一种要求子类实现指定协议的方式,如果一个抽象基类要求实现指定的方法,而子类没有实现的话,当试图创建子类或者执行子类代码时会抛出异常。这里简单介绍一下P...
    99+
    2023-01-31
    三种 抽象 方法
  • C++ 函数继承详解:如何定义和使用抽象基类?
    函数继承允许派生类复用基类的函数定义,通过以下步骤实现:定义抽象基类,包含纯虚函数。在派生类中使用 override 关键字继承并实现基类的函数。实战案例:创建抽象基类 shape,派生...
    99+
    2024-05-03
    c++ 函数继承
  • php能不能定义抽象方法
    这篇文章给大家分享的是有关php能不能定义抽象方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。php能定义抽象方法。PHP5中为了方便类继承,引入抽象方法的概念;抽象方法是没有方法体的方法,PHP中声明抽象方法...
    99+
    2023-06-29
  • 在Python中使用静态,类或抽象方法
    方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数 >>> class Pizza(object): ... def __init__(self, size): ... ...
    99+
    2023-01-31
    抽象 静态 方法
  • 知道java抽象类与抽象方法是什么吗?
    java抽象类与抽象方法是什么?在类的继承中,如果一个个新的子类被定义,子类变得越来越具体,父类变得更加一般和通用,类的设计应该保证父子类能够共享特征,有时将父类设计得非常抽象,使得父类没有具体的实例,这样的类叫做抽象类;一般当我们设计一个...
    99+
    2016-03-20
    java教程 java 抽象类 抽象方法
  • Python中的接口类与抽象类
    面向对象中的继承有两种用途:1)可以通过继承做到代码重用,并完成扩展;2)接口继承。所谓的接口继承就是定义一个接口类 Interface,接口类中定义了一些接口(就是函数,但这些函数都没有具体的实现),子类继承接口类,并且实现接口中的功能...
    99+
    2023-01-31
    接口 抽象类 Python
  • Golang中的抽象类使用方法详解
    Golang中的抽象类使用方法详解 在Go语言中,并没有传统意义上的抽象类和接口继承的概念,但是可以通过结构体嵌套和接口组合来实现类似的功能。本文将详细介绍如何在Golang中实现类似...
    99+
    2024-03-14
    方法 golang 抽象类 go语言
  • java抽象类的使用方法是什么
    在Java中,抽象类是一种不能被实例化的类,通常用于定义一些抽象方法和非抽象方法,用来作为其他类的模板或基类。抽象类使用方法如下: ...
    99+
    2024-03-13
    java
  • Java中抽象类与方法的重写方式
    目录1. 抽象类2. 方法的重写1. 什么情况下需要重写父类中的类型呢?2. @Override 称为注解总结1. 抽象类 关键字:abstract 类:用来描述一类具体的事物 抽象...
    99+
    2023-02-15
    Java抽象类 Java方法重写 抽象类与方法重写
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作