python-深入类和对象

1.鸭子类型与多态

鸭子类型
多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚"鸭子类型"。
动态语言调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

#鸭子类型 在运行之前 Cat,Dog都是在列表里面,当作变量
#当运行时,加上()调用info() 才明确Cat是一个类
class Cat(object):
    def info(self):
        print("i am cat")
class Dog(object):
    def info(self):
        print("i am dog")
class Duck(object):
    def info(self):
        print("i am duck")
animal_list=[Cat,Dog,Duck]
for a in animal_list:
    a().info()

多态
定义时的类型和运行时的类型不一样,就称为多态。

2.抽象基类(abc模块)

抽象基类介绍
抽象基类(abstract base class,ABC):抽象基类就是类里定义了纯虚成员函数的类。纯虚函数只提供了接口,并没有具体实现。抽象基类不能被实例化(不能创建对象),通常是作为基类供子类继承,子类中重写虚函数,实现具体的接口。
抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化。

class Demo(object):
    def __init__(self,li):
        self.li=li
    def __len__(self):
         return len(self.li)
i=["B","狐狸","狼"]
d=Demo(i)
print(d) #<__main__.Demo object at 0x0000020FE8781AC8>
print(len(d)) # 会触发__len__  return len(self.li)  所以 返回3
#如何判断 Demo中 是否 含有 __len__魔法方法
print(hasattr(d,"__len__"))# 判断 d的内部 是否含有__len__   返回值为 布尔 True
"""
可以通过判断 d 是否是 Sized的子类  然后进一步判断 d这个对象的类 是否 含有 __len__方法
"""
from collections.abc import Sized
# 判断d 是否是 Sized 这个类
print(isinstance(d,Sized))    # True 说明d 是Sized 类型

抽象基类应用场景
1.我们去检查某个类中是否有某种方法

class Demo(object):
    def __init__(self,elist):
        self.elist = elist
    def __len__(self):
        return len(self.elist)
d = Demo(["oldAmy", "ls"])
print(len(d))
from collections.abc import Sized
print(isinstance(d, Sized))        # True  d是Sized

查看Sized源码
python安装路径下Lib中的隐藏文件_collections_abc.py

class Sized(metaclass=ABCMeta):
    __slots__ = ()
    @abstractmethod
    def __len__(self):
        return 0
    @classmethod   
    def __subclasshook__(cls, C):
        if cls is Sized:
            return _check_methods(C, "__len__")
        return NotImplemented

注意:
注册的虚拟子类不会继承抽象基类的任何方法和属性
2.我们需要强调某个子类必须实现某些方法
例子:
定义父类Cache
封装CRUD方法。强制子类重写该方法。
定义子类Redis

#方法1 主动抛出异常
class CacheBase(object):
    def dele(self):
        raise NotImplementedError
    def crea(self):
        raise NotImplementedError
class RedisBase(CacheBase):
    """
    1.子类 如果不重写 父类 方法 访问时  直接抛出异常
    """
    def crea(self):
        print("create")
r = RedisBase()
r.crea()
r.dele()
"""
强制子类重写
方法2 抽象基类实现
"""
import abc
# 注意:不是直接继承object 而是继承abc.ABCMeta
class CacheBase(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def dele(self):
        pass
    def crea(self):
        pass
class RedisBase(CacheBase):
    def dele(self):
        pass
r = RedisBase()
"""
抽象基类 : 实例化的时候检测
主动抛出异常 :调用时才会检测
"""

3.type与isinstance区别

type 不考虑 继承关系
isinstance 考虑继承关系

a=1
b='浩子'
print (isinstance(b,(int,str))) # 返回值为布尔值  ()-->or
print(type(a))# <class 'int'>  int
class Father(object):
    pass
class Son(Father):
    pass
ls=Son()
print(isinstance(ls,Son)) # True
print(isinstance(ls, Father)) # True  继承
print(type(ls) is Son) # True
print(type(ls) is Father) # False 并不考虑继承关系 主要 两个类
print(f"Son_id:{id(Son)},Father_id:{id(Father)}")

4.类属性与实例属性

基本查找顺序
对象是可以向上查找的,所以可以访问到类属性
当对象自己有该实例属性时 ,则输出的是自己的
类不能向下查找,所以只能访问到类属性
多继承查询顺序
继承关系如下,则属性查找顺序为
在这里插入图片描述
实际上,python2.2(金典类)之前的算法:MRO算法,DFS(deep first search) 深度优先。
在这里插入图片描述
如下图,菱形继承,执行顺序如何?
在这里插入图片描述
在python2.2版本之后,引入BFS(广度优先)。
在python新式类,就引入了C3算法,通过className.__mro__来查看。
在这里插入图片描述

class Father(object):
    # 类属性
    cls_ins = 1
    def __init__(self, a, b):
        # 实例属性
        self.a = a
        self.b = b
        # self.cls_ins = 886
zs = Father(3, 4)
print(zs.cls_ins, zs.a, zs.b)  # 1 3 4
print(Father.cls_ins)
# print(Father.a)  # 报错
"""
对象 可以向上查找 可以访问到 类属性
类不能向下查找 所以 只能访问到类属性。 类名.实例属性  报错
"""
Father.cls_ins = 778  # 覆盖
zs.cls_ins = 886  # 相当于封装
print(Father.cls_ins)
print(zs.cls_ins)
class MyTest(object):
    ins = "cls_ins"
    def __init__(self):
        self.ins = "ins"
t = MyTest()
print(MyTest.ins)  # cls_ins
print(t.ins)  # ins
"""
当对象 自己有该实例属性的时候  就直接输出自己的
当对象 自己没有该属性的时候 才会向类 向上查找 
"""
# 棱形继承
class D(object):
    pass
class B(D):
    pass
class C(D):
    pass
class A(B, C):
    pass
print(A.__mro__)#(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)

5.Python对象自省机制

自省是通过一定的机制查询到对象的内部结构
Python中比较常见的自省(introspection)机制(函数用法)有: dir(),type(), hasattr(), isinstance(),通过这些函数,我们能够在程序运行时得知对象的类型,判断对象是否存在某个属性,访问对象的属性。

class Perpon(object):
    name = "会太阳"
class Student(Perpon):
    def __init__(self, school_name):
        self.school_name = school_name
hty = Student("Logic_edu")
print(hty.__dict__)  # {'school_name': 'Logic_edu'}  当前对象的属性 {"属性":"属性的值"}
print(dir(hty))  # []  考虑到继承的成员
#{'school_name': 'Logic_edu'}
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'school_name']

6.super函数

# """
# super基础使用
# """
# class A(object):
#     def __init__(self):
#         print("A")
# class B(A):
#     def __init__(self):
#         print("B")
#         # 重写父类的构造方法  再调用父类的方法
#         super().__init__()
# b = B()
"""
软编码与硬编码
"""
# class Person(object):
#     def __init__(self, name, age, weight):
#         self.name = name
#         self.age = age
#         self.weight = weight
#     def speak(self):
#         print(f"{self.name}说:我{self.age}岁")
# class Student(Person):
#     def __init__(self, name, age, weight, grade):
#         self.grade=grade
#         # 软编码 -> 父类的名字可以随便更改
#         super().__init__(name, age, weight)
#         # 硬编码
#         # Person.__init__(self, name, age, weight)
#         # self.grade = grade
#     def speak(self):
#         print(f"{self.name}说:我{self.age}岁,我在{self.grade}年级,我体重{self.weight}")
# hz = Student('hz', 20, 120, 2)
# hz.speak()
 # super函数的继承机制
class A(object):
    def __init__(self):
        print("A")
class C(A):
    def __init__(self):
        print("B")
        super().__init__()
class B(A):
    def __init__(self):
        print("C")
        super().__init__()
class D(B,C):
    def __init__(self):
        print("D")
        super().__init__()
if __name__ == '__main__':
    d = D()
    print(D.__mro__)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值