• python面对对象编程---------6:抽象基类


     抽象基本类的几大特点:

        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

    来看一个简单的抽象类
     1 __dict__:方法名+属性名
     2 __mro__:  包含此类所有父类的元祖
     3 >>> class aha(list):
     4        def __init__(self,value):
     5            super().__init__(value)
     6 
     7 
     8 >>> a=aha('pd')
     9 >>> a
    10 ['p', 'd']
    11 >>> aha.__dict__
    12 mappingproxy({'__weakref__': <attribute '__weakref__' of 'aha' objects>, '__doc__': None, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'aha' objects>, '__init__': <function aha.__init__ at 0x030967C8>})
    13 >>> aha.__mro__
    14 (<class '__main__.aha'>, <class 'list'>, <class 'object'>)
    __dict__与__mro__
     1 from abc import ABCMeta, abstractmethod
     2 class AbstractBettingStrategy(metaclass=ABCMeta):
     3     __slots__ = ()
     4     @abstractmethod
     5     def bet(self, hand):
     6         return 1
     7     @abstractmethod
     8     def record_win(self, hand):
     9         pass
    10     @abstractmethod
    11     def record_loss(self, hand):
    12         pass
    13     @classmethod                                #检查了三个用抽象方法在子类中是否implement,否则报错。
    14     def __subclasshook__(cls, subclass):
    15         if cls is Hand:
    16             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__)):
    17                 return True
    18         return NotImplemented
    19 
    20 class Simple_Broken(AbstractBettingStrategy):
    21     def bet( self, hand ):
    22         return 1
    23 # The preceding code can't be built because it doesn't provide necessary implementations for all three methods.
    24 # The following is what happens when we try to build it:
    25 >>> simple= Simple_Broken()
    26 Traceback (most recent call last):
    27 File "<stdin>", line 1, in <module>
    28 TypeError: Can't instantiate abstract class Simple_Broken with
    29 abstract methods record_loss, record_win
    #注,上例可能太过严格,有些子类并不需要实现其所有方法,这个需要具体情况再看

    #注,此篇可能看起来有点不太逻辑清晰,这源于我对collections.abc以及number模块目前还不太清晰,等改天研究明白了来改改,加些内容,此时先放出来占个位
  • 相关阅读:
    浏览器中使用js跨域获取数据
    Flash和JavaScript通信
    display
    流媒体,hls
    防止字溢出
    <head>头部
    ps图层填充颜色——先选好颜色,再选中需要填充颜色或者修改颜色的图层,最后按住Alt+Delete键。完成。
    div相对于浏览器窗口居中、图片相对于外层的div居中
    CSS绘制三角形
    点击A页面链接,跳转至B页面指定位置
  • 原文地址:https://www.cnblogs.com/pengsixiong/p/5382768.html
Copyright © 2020-2023  润新知