抽象基类(abc模块) isinstance 和 type的区别及super 函数

抽象基类(abc模块)

# 抽象基类(abc模块)
# 抽象基类(abstract base class.ABC): 抽象基类就是类里定义了纯虚成员函数的类
# 纯虚函数只是提供了接口,并没有具体实现,抽象基类不能被实例化(不能创建对象)
# 通常是作为基类供子类继承,子类中重写虚函数,实现具体的接口。

# 抽象基类就是定义各种方法而不做具体实现有类,任何继承自抽象基类

# 应用场景
# 1. 判断某个对象的类型
# 2. 我们需要强制某个子类必须实现某些方法

# 使用isinstance 和 type的区别

class Demo(object):
    def __init__(self, names):
        self.names = names

    def __len__(self):  # Sized 有__len__方法 返回True
        return len(self.names)

    def __iter__(self):  # 查看原代码可以找到Iterable有__iter__方法 返回True
        pass

    def test(self):
        pass


d = Demo(['ellen', 'python'])

print(len(d))

print(hasattr(d, 'test'))  # 判断是否有这个方法

from collections.abc import Sized,Iterable

print(isinstance('demo', int))  # 判断类型 判断实例
print(isinstance(d,Sized))
print(isinstance(d,Iterable))


'''
2. 我们需要强制某个子类必须实现某些方法
web cache redis memcache 如果自己写了一个web框架要集成cache缓存,有redis缓存和memcache缓存
这些缓存要自己去实现,还有一个缓存基类,也就是说这个类有一些方法必须在子类中才能实现,必须要继承才能实现

'''
import abc


class CacheBase(metaclass=abc.ABCMeta):
   @abc.abstractmethod
    def get(self, key):
        #raise ValueError
        pass

   @abc.abstractmethod
    def set(self, key, value):
        # raise NotImplementedError
        pass
        # self.key = key

class RedisBase(CacheBase):
    # 重写父类中的方法
    def get(self, key):
        pass

    def set(self,key,value):
        pass

r = RedisBase()
#r.get('ellen')

使用isinstance 和 type的区别

# 使用isinstance 和 type的区别

# i = 1
# s = 'ellen'


# print(isinstance(1,int))
# print(isinstance(s,int))
# print(isinstance(s,str))

# print(type(i))

# if isinstance(i,int):    #  返回123
# if type(i) == 'int':   # 不会打印
# print(123)


# class A:
#     pass
#
# class B(A):
#     pass

# b = B()
# print(isinstance(b,B))      # True
# print(isinstance(b,A))      # True  考虑类的继承关系
#
# print(type(b) is B)          # True
# print(type(b) is A)          # False 没有考虑类的继承关系
# == value 是数值
# is 是内存地址
# 区别


class A:
    # 类属性
    aa = 1

    # 实例方法
    def __init__(self, x, y):
        # 实例属性
        self.x = x
        self.y = y
       # self.aa = 22   # 在外部定义a.aa = 22 相当于在内部方法添加了实例属性

a = A(1, 2)
# print(a.x, a.y, a.aa)   # 可以向上查找

# print(A.x)   # 报错  不能向下查找

# print(A(1,2).x)  # 1 可以查找
A.aa = 11
a.aa = 22
print(a.aa)   # 22
print(A.aa)   # 11

b = A(1,2)
print(b.aa)     # 11

super 函数

# super 函数
# 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时
# 我们就需要调用父类的方法了,可能过使用super来实现
class A:
    def __init__(self):
        print('A')


class B(A):
    def __init__(self):
        print('B')
        super().__init__()

# 重写了B的构造函数 为什么还要去调用super
# super 执行顺序到底是什么样的?

b = B()


class People(object):
    def __init__(self,name,age,weight):
        self.name = name
        self.age = age
        self.weight = weight

    def speak(self):
        print('%s 说: 我%d岁了'%(self.name,self.age))

class Student(People):
    def __init__(self,name,age,weight,grade):
       # super().__init__(name,age,weight)
        People.__init__(self,name,age,weight)
        self.grade =grade


s = Student('ellen',18,90,3)
s.speak()


class A:
    def __init__(self):
        print('A')


class B(A):
    def __init__(self):
        print('B')
        super().__init__()


class C(A):
    def __init__(self):
        print('C')
        super().__init__()

class E:
    pass

class D(B,C,E):
    def __init__(self):
        print('D')
        super().__init__()


d = D()
print(D.__mro__)    # D B C A
# super 调用父类中的方法
# 而是按照mro 算法来调用的
发布了106 篇原创文章 · 获赞 0 · 访问量 2395

猜你喜欢

转载自blog.csdn.net/weixin_45905671/article/details/105256327