抽象基本类的几大特点:

    1:要定义但是并不完整的实现所有方法
2:基本的意思是作为父类
3:父类需要明确表示出那些方法的特征,这样在写子类时更加简单明白 用抽象基本类的地方:
1:用作父类
2:用作检验实例类型
3:用作抛出异常说明
关于抽象基本类的几点说明:
1:LSP(里式替换原则):
子类必须能够替换他们的基类型,替换后软件运行形态不变,觉察不出基类和子类的区别。
这样来检验该设计是否合理或者藏有缺陷。(从抽象类继承而不是具体类) 2:关于isinstance的使用:
首先:大量的isinstance检测会造成复杂而缓慢的程序还表明多态设计不好
其次:在使用isinstance时更加pythonic的用法是处理错误而不是请求许可
1:请求许可:
assert isinstance( some_argument, collections.abc.Container ),"{0!r} not a Container".format(some_argument)
尽管很简洁,但是有两个缺点: assertions can be silenced, and it would probably be better to raise a TypeError for this:
if not isinstance(some_argument, collections.abc.Container):
raise TypeError( "{0!r} not a Container".format(some_argument))
2:处理异常
try:
found = value in some_argument
except TypeError:
if not isinstance(some_argument, collections.abc.Container):
warnings.warn( "{0!r} not a Container".format(some_argument) )
raise 3:Containers and collections
container(容器),既是其可以包含多个对象,其实是多个reference的集合的概念,python内置的containers有比如list,map,set.
    collections是python内建的一个集合模块,提供了许多可用的集合类,如namedtuple,deque,defalutdict等等。
总结:container是一个抽象类而collections是继承了container并实现了多种子类数据结构如namedtuple,deque,chainmap,counter,ordereddict,defaultdict的类的统称 container应该实现的:
Lower-level features include Container, Iterable, and Sized.
they require a few specific methods, particularly __contains__(), __iter__(), and __len__(), respectively collections应该实现的:
Sequence and MutableSequence: These are the abstractions of the concrete classes list and tuple. Concrete sequence implementations also include bytes and str.
          MutableMapping: This is the abstraction of dict. It extends Mapping, but there's no built-in concrete implementation of this.
          Set and MutableSet: These are the abstractions of the concrete classes,frozenset and set.
   This allows us to build new classes or extend existing classes and maintain a clear and formal integration with the rest of Python's built-in features. python中两大抽象基类:
  1:各种数据类型相关的collections.abc

    >>> abs(3)
    3
    >>> isinstance(abs, collections.abc.Callable)
    True

    >>> isinstance( {}, collections.abc.Mapping )
    True
    >>> isinstance( collections.defaultdict(int), collections.abc.Mapping)
    True

  

  2:数值相关的numbers

    >>> import numbers, decimal
    >>> isinstance( 42, numbers.Number )
    True
    >>> isinstance( 355/113, numbers.Number ) #由此可见,integer和float都是number.Number类的子类
    True
    >>> issubclass( decimal.Decimal, numbers.Number ) #decimal.Decimal是numbers.Number的子类
    True
    >>> issubclass( decimal.Decimal, numbers.Integral )
    False
    >>> issubclass( decimal.Decimal, numbers.Real )
    False
    >>> issubclass( decimal.Decimal, numbers.Complex )
    False
    >>> issubclass( decimal.Decimal, numbers.Rational )
    False
来看一个简单的抽象类
 __dict__:方法名+属性名
__mro__: 包含此类所有父类的元祖
>>> class aha(list):
def __init__(self,value):
super().__init__(value) >>> a=aha('pd')
>>> a
['p', 'd']
>>> aha.__dict__
mappingproxy({'__weakref__': <attribute '__weakref__' of 'aha' objects>, '__doc__': None, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'aha' objects>, '__init__': <function aha.__init__ at 0x030967C8>})
>>> aha.__mro__
(<class '__main__.aha'>, <class 'list'>, <class 'object'>)

__dict__与__mro__

 from abc import ABCMeta, abstractmethod
class AbstractBettingStrategy(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def bet(self, hand):
return 1
@abstractmethod
def record_win(self, hand):
pass
@abstractmethod
def record_loss(self, hand):
pass
@classmethod #检查了三个用抽象方法在子类中是否implement,否则报错。
def __subclasshook__(cls, subclass):
if cls is Hand:
if (any("bet" in B.__dict__ for B in subclass.__mro__) and any("record_win" in B.__dict__ for B in subclass.__mro__) and any("record_loss" in B.__dict__ for B in subclass.__mro__)):
return True
return NotImplemented class Simple_Broken(AbstractBettingStrategy):
def bet( self, hand ):
return 1
# The preceding code can't be built because it doesn't provide necessary implementations for all three methods.
# The following is what happens when we try to build it:
>>> simple= Simple_Broken()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Simple_Broken with
abstract methods record_loss, record_win
#注,上例可能太过严格,有些子类并不需要实现其所有方法,这个需要具体情况再看
#注,此篇可能看起来有点不太逻辑清晰,这源于我对collections.abc以及number模块目前还不太清晰,等改天研究明白了来改改,加些内容,此时先放出来占个位

python面对对象编程---------6:抽象基类的更多相关文章

  1. python面对对象编程----------7:callable(类调用)与context(上下文)

    一:callables callables使类实例能够像函数一样被调用 如果类需要一个函数型接口这时用callable,最好继承自abc.Callable,这样有些检查机制并且一看就知道此类的目的是c ...

  2. python面对对象编程----2:__init__

    面对对象编程估计我们最早接触到的就是__init__了,也就是实例的初始化处理过程: 1:来看看最基础的__init__ class Card(object): #抽象类Card,并不用于实例化 de ...

  3. python面对对象编程------4:类基本的特殊方法__str__,__repr__,__hash__,__new__,__bool__,6大比较方法

    一:string相关:__str__(),__repr__(),__format__() str方法更面向人类阅读,print()使用的就是str repr方法更面对python,目标是希望生成一个放 ...

  4. python面对对象编程-------5:获取属性的四种办法:@property, __setattr__(__getattr__) ,descriptor

    一:最基本的属性操作 class Generic: pass g= Generic() >>> g.attribute= "value" #创建属性并赋值 > ...

  5. python面对对象编程中会用到的装饰器

    1.property 用途:用来将对像的某个方法伪装成属性来提高代码的统一性. class Goods: #商品类 discount = 0.8 #商品折扣 def __init__(self,nam ...

  6. python面对对象编程----1:BlackJack(21点)

    昨天读完了<Mastering Object-oriented Python>的第一部分,做一些总结. 首先,第一部分总过八章,名字叫Pythonic Classes via Specia ...

  7. python 用abc模块构建抽象基类Abstract Base Classes

    见代码: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/08/01 16:58 from abc import ABCMet ...

  8. python面对对象编程------3:写集合类的三种方法

    写一个集合类的三种方法:wrap,extend,invent 一:包装一个集合类 class Deck: def __init__( self ): self._cards = [card6(r+1, ...

  9. C++ 基础语法 快速复习笔记---面对对象编程(2)

    1.C++面对对象编程: a.定义: 类定义是以关键字 class 开头,后跟类的名称.类的主体是包含在一对花括号中.类定义后必须跟着一个分号或一个声明列表. 关键字 public 确定了类成员的访问 ...

随机推荐

  1. 如何调整iMindMap打印设置

    打印何尝不是一种保存.导出iMindMap思维导图的一种方法,我们还可以通过调整打印设置来满足我们不同的需求.下面小编就给你翻一翻iMindMap中文版教程,教你怎样调整打印设置. 我们在打开iMin ...

  2. 转:PHP之Traits

    原文来自于:http://www.cnblogs.com/tekkaman/archive/2012/12/12/2814214.html 1.Traits基础 2.优先级:当前类中的方法会覆盖 Tr ...

  3. Flux

    Ken Wheeler 构建React 应用的一套架构.  应用程序架构, 单向数据流方案. Dispatcher 的开源库.   一种全局pub/sub 系统的事件处理器, 用于 向所注册的加调函数 ...

  4. 趁有空,再了解一下GROOVY中关于类的通例

    简单的,浅浅的看一下. 想起了RUBY里覆盖类的方法... 在GROOVY里也同样提到了,比如TOSTRING... (其实,在我以前的经验中,从未用过这些东东..:)) 这样用了PACKAGE,显得 ...

  5. Response对象

    Response对象来自HttpResponse类,它用于向客户端输出信息或设置客户端输出状态,使用Response对象可以直接发送信息给浏览器.重定向浏览器到另一个URL或设置cookie的值等. ...

  6. UpdateLayeredWindow是炫效果的关键

    自绘——是的,输入框每个字都自己绘制,计算行宽,行高,模拟光标闪烁,处理输入法的各种事件,以及选中,拖动等功能. 支持支持一下,实际上无句柄的,就是多行富文本编辑比较麻烦,其他的,都不复杂.很容易实现 ...

  7. 设置Tomcat默认界面

    修改配置文件:         首先,修改$tomcat/conf/server.xml文件.      在server.xml文件中,有一段如下:      ……      <engine   ...

  8. Linux Shell编程(4)——shell特殊字符(上)

    在脚本或其他别的地方出现的特殊字符#注释. 以一个#开头的行 (#!是例外) 是注释行.# 这是一行注释.注释也可以出现在一个命令语句的后面.echo "A comment will fol ...

  9. Linux系统下UDP发送和接收广播消息小例子

    // 发送端 #include <iostream> #include <stdio.h> #include <sys/socket.h> #include < ...

  10. 【宽搜】Vijos P1360 八数码问题

    题目链接: https://vijos.org/p/1360 题目大意: 3x3格子上放1~8数字,一个空位,每次空位可与上下左右交换,固定终止布局,求输入的起始布局需要几步到达终止布局 题目思路: ...