zoukankan      html  css  js  c++  java
  • Python-面向对象

    # 开闭原则 对扩展开放,对修改关闭

    面向对象

      组织和构建代码逻辑的一种思路,面向对象是主流的一种编程范式而已,还有面向过程和面向函数编程范式,但在在Python中面向对象最为彻底,一切皆对象

     

    与类相关的概念

      类、实例 、类方法、类变量、实例方法、实例变量

     

    类相关的关键字 class @ staricmethod classmethod property setter

     

    类考虑的主体是什么?

      1. 类考虑的是群体与群体的统计数据和公共行为

      2. 对象考虑单个个体的特征数据和行为

     

    什么是抽象?

      移除细节,看主干,从众多的事物中抽出共同的、本质性的特征,舍弃其非本质的特征,总体归结4个字: 提取共性 

     

    类的作用是什么?

      1. 封装和组织代码架构

      2. 只定义不运行,一个模块一个或多个类,通过导入实例化使用

     

    什么是类?

      人以类聚,物以群分。考虑的是群体的特征,把群体的特征抽象出来形成单独的类,依据有的群体有那就其他的群体没有的界限进行群体分类,这就是类。

     

    什么是实例?

      我们不一样,这就说明同时身为人类这个大类,但我们身上的具体特征属性各不相同,也就是通过差异化数据填充到类中,从而实现实例化,考虑的是类中单个个体的具体的特性数据和行为,是一种粒度比类小的一种抽象

     

    什么是类变量?

      群体相关的统计特征数据,每个实例都共享这个数据

     

    什么是类方法?

      群体都具有的行为,可以对群体特征数据进行操作

     

    什么是实例变量?

      单个个体的特征数据,也是一种抽象,粒度比较小的抽象,通过填充不同的数据值,生成完全不同的实例对象

     

    什么是实例方法?

      单个个体的特征行为,对个体实例变量进行操作,是粒度比较小的抽象,赋予实例对象行为

     

    Python 类整体架构 

    class ExtendClass:
        pass
    
    
    class ClassName(ExtendClass):
        """通过实例变量和实例方法前加 _ 前缀约定为私有"""
    
        # 类变量
        class_variable = class_value
    
        def __init__(self):
            """初始化实例变量"""
            # 调用父类中析构函数
            super().__init__()
            # 私有属性,约定外部不可访问
            _variable = object_value
            # 公有属性,外部可以访问
            variable = object_value
            pass
    
        def func(self):
            """公有实例方法,约定外部可访问"""
            pass
    
        def _func(self):
            """私有实例方法,约定外部不可方法"""
            # 调用父类方法
            super().func()
            pass
    
        def __func__(self):
            """Python协议又被称为魔法方法,给对象增强属性,重要的鸭子类型的实现"""
            pass
    
        @classmethod
        def func(cls):
            """类方法,有个@classmethod装饰器,只能访问类变量"""
            pass
    
        @staticmethod
        def func():
            """静态方法,不需要访问任何类变量和实例变量"""
            pass
    
        @property
        def func(self):
            """调用属性一样调用方法"""
            pass
    

      # 这只是类的架构图(伪代码)

     

    类名命名规范:

      1. 遵循变量名命名规范

      2. 驼峰命名方式,首字母大写并且通过首字母大写区分单词

     

    类变量和类方法特性

      1. 同类的实例共享

      2. 通过类方法进行访问和修改,当前也可以直接访问

    class BeiMenChuiXue:
        object_number = 0
    
        @classmethod
        def add_one_object(cls):
            cls.object_number += 1
    
        @classmethod
        def get_object_number(cls):
            return cls.object_number
    
    
    if __name__ == '__main__':
        bei_men_chui_xue = BeiMenChuiXue()
        BeiMenChuiXue.add_one_object()
        xi_men_chui_feng = BeiMenChuiXue()
        BeiMenChuiXue.add_one_object()
        # 通过类名和方法访问
        print(BeiMenChuiXue.get_object_number())
        print(BeiMenChuiXue.get_object_number())
        # 通过直接访问
        print(BeiMenChuiXue.object_number)
        print(bei_men_chui_xue.__class__.object_number)
        # 也可以通过实例访问,这个根实例属性查找策略相关
        print(bei_men_chui_xue.get_object_number())
    

      

    析构函数和实例方法特性

      1. 当实例化对象的时候,会自动调用__init__函数,不需要显式调用

      2. 如果显示调用__init__函数则相当于普通函数,除了能返回None,其他都不能返回

      3. 如果__init__传递参数,则实例化对象的时候需要传递参数,约定实例变量和形参同名

      4. 定义实例方法的时候,self必须作为第一个参数,其实是当前调用实例本身,Python中显胜于隐原则

      5. 通过添加 _前缀约定为私有

    class BeiMenChuiXue:
        def __init__(self, name, age):
            self.name = name
            self.age = age
            self._country = None
    
        def get_name(self):
            return self.name
    
        def get_age(self):
            return self.name
    
        def _get_country(self):
            return self._country
    
        def set_country(self, country):
            if country == self._get_country():
                pass
            else:
                self._country = country
    
        def user_country(self):
            return self._country
    
    
    if __name__ == '__main__':
        bei_men_chui_xue = BeiMenChuiXue(name="北门吹雪", age=18)
        print(bei_men_chui_xue.get_age())
        print(bei_men_chui_xue.get_name())
        bei_men_chui_xue.set_country("中国")
        print(bei_men_chui_xue.user_country())
    

     

    其实本质上,通过__双下划线进行约束实例变量和方法为私有方法,Python会将这个变量或实例方法前添加了__ClassName前缀,本质上还是能访问到的

    class BeiMenChuiXue:
    
        # def __get_name(self):
        #     print("北门吹雪")
        def __init__(self, name):
            self.__name = name
    
    
    if __name__ == '__main__':
        bei_men_chui_xue = BeiMenChuiXue("北门吹雪")
        print(vars(bei_men_chui_xue))
        print(bei_men_chui_xue._BeiMenChuiXue__name)
    

     

    使用类的过程

      1. 定义类

      2. 实例类

      3. 调用实例方法或类方法

     

    相关概念理清:

      1. 成员函数就是实例方法

      2. 成员变量就是实例变量

     

    静态方法

      属于这个类的一部分,不访问类变量和实例变量的方法

    class BeiMenChuiXue:
        country = None
    
        def __init__(self, name):
            self.name = name
    
        @staticmethod
        def go_hello():
            print("Hello World!")
    
    
    if __name__ == '__main__':
        bei_men_chui_xue = BeiMenChuiXue("北门吹雪")
        bei_men_chui_xue.go_hello()
    

      

    属性方法

      可以像访问属性和属性赋值访问实例方法,必须先定义 property方法才能定义 setter方法,在 property方法的基础上, 以 property装饰的函数为基础

    class BeiMenChuiXue:
        country = None
    
        def __init__(self, name):
            self.name = name
    
        @property
        def get_name(self):
            return self.name
    
        @get_name.setter
        def set_name(self, new_name):
            self.name = new_name
            pass
    
    
    if __name__ == '__main__':
        bei_men_chui_xue = BeiMenChuiXue("北门吹雪")
        bei_men_chui_xue.set_name = "beimenchuixue"
        print(bei_men_chui_xue.get_name)
    

    Python super查找路径  

      super其实本质上和父类没有一点关系,查找__mro__属性(类名.mor())的下一个类,只要其中一个属性或多个属性符合,则调用这个类的方法和实例变量,而不再调用其他类中__init__方法,需要核心注意,并不是完全继承。

    class Student:
        def __int__(self, age, school):
            self.name = age
            self.school = school
    
    
    class Person:
        def __init__(self, name, skin):
            self.name = name
            self.skin = skin
    
    
    class BeiMenChuiXue(Person, Student):
        def __init__(self, name, skin, age, school):
            print(BeiMenChuiXue.__mro__)
            # 这句会报错,因为 满足 name 和 skin的类是 Person类,就调用Person的析构函数__init__
            # 但是Person的析构函数__init__没有对age和school进行初始化,所以报参数给多的错误
            super().__init__(name, skin, age, school)
    
    
    if __name__ == '__main__':
        bei_men_chui_xue = BeiMenChuiXue(name="北门吹雪", skin='yellow', age=19, school="Python")
        print(vars(bei_men_chui_xue))
    

    面向对象三大特性

      1. 封装, 类变量、实例变量、类方法、实例方法放在了一个类中

      2. 继承,Python支持多继承,不推荐,推荐使用单继承树,多继承使用Minix思想继承,继承的类之间完全隔离不相干

      3. 多态,Python通过鸭子类型实现多态,上面的属性方法也是多态的一种,但更多的是Python协议实现多态,也被称为魔法方法

    经验:

      1. 类将数据和数据的操作放在了一起,刻画某些事物的特性,总体上是一种抽象,核心为特征和行为,考虑的方式是群体与群体的划分

      2. 实例对象是类中个体与个体之间的抽象,同填充具体的数据生成具体的个体对象

      3. 约定属性前面添加一个下划线为私有属性,虽然双下划线也可以,但很多的优秀的库都是如此写的,Python并没有真正意义上限制属性的访问

      4. 变量刻画特征,方法刻画行为并改变特征变量

      5. 类查找相关变量首先找实例变量,然后找类变量,最后去父类中去找,约定按 __mro__顺序找

      6. 封装最基本的原则,接收定义复杂不接受调用复杂

  • 相关阅读:
    指针与数组的区别 —— 《C语言深度剖析》读书心得
    console ouput 与 重定向输出 效率对比
    First day in 阿里
    TestNG 使用入门教程
    Spring简单使用简介
    玩转Spring JUnit+mockito+powermock单元测试(使用详解)
    Spring Boot Junit 单元测试详解
    spring @Value注入map、List、Bean、static变量方式及详细使用
    单元测试Junit使用详解
    Mockito & PowerMock详解
  • 原文地址:https://www.cnblogs.com/2bjiujiu/p/9139600.html
Copyright © 2011-2022 走看看