• CSIC_716_20191127【组合,封装、类的私有属性方法、property装饰器】


    组合

    what?   组合是指一个对象中,包含另一个或多个对象。

    why?      减少代码的冗余。

    How?     在类中加入其他类的对象,实现跨类对象之间的联动。

    耦合度  软件设计要 高内聚,低耦合。

    耦合度越高,程序的可扩展性越低

    耦合度越低,程序的可扩展性越高

    继承与组合的区别:

    继承代表【是】的关系,是类和类之间的关系,老师类是人类,学生类是人类。子类和父类是从属关系。

    组合代表【有】的关系,是对象和对象之间的关系,老师对象 有 课对象,学生对象 有 课对象。表示拥有某种属性或者方法。

    组合

    组合的精髓在与将一个对象作为某个类的特有属性,然后通过该特有属性(赋的是其他类的对象的值)再去调用对象所在类的方法,实现多种功能的拼接。

    举例:

    # _*_ coding: gbk _*_
    # @Author: Wonder
    '''
    练习需求:
        选课系统:
            1.有学生、老师类,学生与老师有属性 “名字、年龄、性别、
    
            课程”,
            2.有方法 老师与学生可以添加课程,
    
            打印学习/教授课程。
    
        # 组合实现
    '''
    
    
    class People:
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def add_course(self, course_obj):
            self.course_list.append(course_obj)
    
        def course_info(self):
            for course_obj in self.course_list:
                course_obj.show()#通过对象去找该对象能取到的方法
    
    
    class Teacher(People):
        def __init__(self, name, age, gender):
            super().__init__(name, age, gender)
            self.course_list = []  #存放交互对象的容器
    
    
    class Student(People):
        def __init__(self, name, age, gender):
            super().__init__(name, age, gender)
            self.course_list = []
    
    
    class Course:
        def __init__(self, course_name, course_price, course_cycle):
            self.course_name = course_name
            self.course_price = course_price
            self.course_cycle = course_cycle
    
        def show(self):
            print(f'''
                =======选的课为:=======
                course_name = {self.course_name}
                course_price = {self.course_price}
                course_cycle = {self.course_cycle}
                ''')
    
    
    t1 = Teacher('abc', 19, 'male')
    python_obj = Course('PYTHON', 10000, '6month')  # 统一称之为course_obj
    go_obj = Course('GO', 5000, '4month')
    t1.add_course(python_obj)
    t1.add_course(go_obj)
    t1.course_info()  t1永远只会调用自己本身或者父类的函数,组合的类,由组合的对象去调用
    

      

    封装

    什么是封装:将一堆属性和方法封装到对象中去,可以通过【对象名.】的方式进行调用。

    封装使得对数据的提取更加方便。

    封装中的访问限制机制

    what   凡是在类内部定义的属性和方法,以__开头的属性和方法,都会被限制,外部不能直接使用该属性原型。类似于将该属性或方法隐藏起来了。通过在属性或函数前面加上 _ _将该属性或方法隐藏起来,   本质上是一种变形操作。    _ _name  等价于  _ 类名_ _ 属性名

    why   可以将一些隐私数据隐藏起来,不让外部轻易获取。

        可以将一堆数据封装成接口,让用户直接调用,并通过相应的逻辑,最后将数据返回。

    how :如果知道类名以及被隐藏是数据或者方法名,可以通过【_类名__属性/方法名】进行调用

    例如  :

    # _*_ coding: gbk _*_
    # @Author: Wonder
    class People:
        __school = 'HEU'
    
        def __init__(self, name, age, gender):
            self.__name = name
            self.__age = age
            self.__gender = gender
    
        def __show(self):
            print('隐藏了吗')
    
    
    human1 = People('wonder', 19, 'male')
    print(human1.__school)  #People' object has no attribute '__school'
    print(human1._People__school)  #HEU
    
    print(human1.__name)  # AttributeError: 'People' object has no attribute '__name'
    print(human1._People__name)  #wonder
    
    human1.__show()  # AttributeError: 'People' object has no attribute '__show'
    human1._People__show()  # 隐藏了吗
    

      

    用_ _隐藏的主要目的是想将属性或者方法限制在类中使用,不想被外界调用。

    property本质上是一个装饰器,用来装饰类内部的方法(在被装饰方法上方,使用语法糖@property,进而将  原先的【类名.方法名()】调用方式改变为【类名.方法名】

    如果被property装饰过的方法,想要改变他的值,只可以通过@被装饰方法名.setter以及@被装饰方法名.deleter进行修改和删除操作。

    # _*_ coding: gbk _*_
    # @Author: Wonder
    # class Securty:
    #     def __init__(self, name, gender, height, weight):
    #         self.__name = name
    #         self.gender = gender
    #         self.height = height
    #         self.weight = weight
    #
    #     def hw(self):
    #         return (self.height + self.weight)
    #
    #     @property
    #     def sex(self):
    #         return self.gender
    #
    #     @property
    #     def namey(self):
    #         return self.__name
    
    # s1 = Securty('wonder', 'male', 190, 200)
    # print(s1.hw())  # 390
    # print(s1.sex())  # TypeError: 'str' object is not callable
    # print(s1.sex)  # male
    # print(s1.namey)  # wonder
    

      

    __name是可以被return出来的。见上面红色背景的语句及执行结果。

    # 想修改或删除被property装饰的属性
    class Sure:
        def __init__(self, name, ):
            self.__name = name
    
        @property
        def namey(self):
            return self.__name
    
        @namey.setter
        def namey(self, value):
            if not isinstance(value, str):
                raise TypeError('FUCK_NO')
            self.__name = value
    
        @namey.deleter
        def namey(self):
            # del self.__name  # 执行删除操作
            # 如果将改为raise TypeError('forbidden')
            raise TypeError('forbidden')
    
    
    name1 = Sure('GOOGLE')
    print(name1.namey)  # GOOGLE
    name1.namey = 'YAHOO'  # 修改值操作
    print(name1.namey)  # YAHOO
    del name1.namey  #删除操作
    print(name1.namey)  # 如果删除了,则会报错AttributeError: 'Sure' object has no attribute '_Sure__name'。否则还是YAHOO
    

      

  • 相关阅读:
    新思路:Exception Handle
    转战github了
    矩阵内积和Schur补
    原子范数及线谱估计
    次梯度方法
    机器学习——推荐系统
    机器学习——异常值检测
    机器学习——聚类分析和主成分分析
    常用不等式集锦
    机器学习——支持向量机(SVM)
  • 原文地址:https://www.cnblogs.com/csic716/p/11943762.html
Copyright © 2020-2023  润新知