美文网首页
Python学习总结【连载】(十三)

Python学习总结【连载】(十三)

作者: Juttachen_8e9d | 来源:发表于2018-07-01 16:51 被阅读35次

    Python学习总结【连载】(十三)

    2018.06.28 Juttachen


    概述

    • 42 属性私有化
    • 43 假的私有属性
    • 44 类字段和类方法
    • 45 静态方法
    • 46 类的继承
    • 47 类的继承重写

    四十二、属性私有化(了解)

    1.访问权限

    属性的访问权限:
    公开、保护(python中没有)、私有
    公开: 指的是在类的外部可以直接使用(默认)
    公开属性: 属性名是普通单词(字符串,就是不以两个下划线开头的属性)
    私有: 只能在类的内部直接使用,但是可以间接使用
    私有属性: 属性名以两个下划线开头(一定不以下划线结束)

        class Person:
            """人"""
            def __init__(self,name='',age=0):
                # name属性是公开的属性
                self.name = name
                self.__age =age
    
            def show(self):
                print(self.name)
                # 私有属性可以在类的内部使用
                print(self.__age)
    
        p1 = Person('小明')
        print(p1.name)
        # 私有属性不能在类的外部使用
        # print(p1.__age) # AttributeError:'Person' object has no attribute '__age'
    
        p1.show()
    

    四十三、假的私有属性

    实际开发中,声明类的属性,很少会使用真正的私有属性(前面加两个下划线的)。
    实际对属性的要求:
    1.可以通过对象.属性语法方便的给属性赋值或者拿到他的值(所以不能是私有的)
    2.给属性赋值的时候,需要对付过来的值进行规范,不能直接就让值赋给属性(所以不能是公开的)
    如何满足要求:就使用假的私有属性 + getter 和 setter

    1. 声明属性,属性名前加一个下划线(这是一个规范,不是语法:带一个下划线的属性,不要直接通过一个下划线对应的属性名去访问这个属性)
    2. 通过给属性添加getter和setter来限制赋值和获取值的过程
      a. 添加getter(是一种方法):-->目的:限制获取属性值的操作,-->getter的作用:返回属性的值
      格式:

    @property
    def 前面不带下划线的属性名(self):
    其他任何操作
    return self.带一个下划线的属性名

    b.添加setter
    格式:

    @去掉下划线的属性名.setter
    def 去掉下划线的属性名(self, 参数):
    其他任何操作
    self.带下划线的属性名 = 参数

    1. 在类的外部通过不带下划线的属性去获取属性的值,或者给属性赋值

       class Person:
           def __init__(self,name='',age=0):
               self.name = name 
               self.age = age
      
       p1 = Person()
       p1.name = '小明'
       p1.name = 100 # 公开化就可以随意改变值的数据类型
       p1.name = ['',1] # 甚至是对象都可以赋
      

    例子

        class Person:
            def __init__(self,name='',age=0):
                self._name = name 
                self._age = age
    
            # 给_name属性添加getter
            @property
            def name(self):
                if len(self._name) == 0:
                    return '无名氏'
                return self._name
    
            # 给_name属性添加setter
            @name.setter
            def name(self, name1):
                self._name = name1
    
            # 给_age属性添加getter
            @property
            def age(self):
                # 判断是否是int类型
                if isinstance(self._age,int) == False:
                    return '属性错误'
                # 判断是不是为0
                if self._age == 0:
                    return '还未诞生'
                return self._age
    
            @age.setter
            def age(self,age1):
                self._age = age1    
        p1 = Person()
        # print(p1._name) #是不会报错的,但不推荐使用
        print(p1.name) #有了getter再写p1.name就没有问题了
        p1.name = "路飞"
        print(p1.name)
        p1.age = 17
        print(p1.age)
    

    注意:
    1.getter一般要添加,setter可以不用写(实际运用中,一般只加getter)
    2.如果要添加setter必须添加getter

    实例二:getter 和 setter 的使用以及关系

        class Cat:
            """猫"""
    
            def __init__(self,name='',color=''):
                self._name = name
                self._color = color
    
        cat1 = Cat('小花','yellow')
        cat1._name = '喵喵'  #推荐
        print(cat1._name)  #不推荐
    

    四十四、类字段和类方法

    1.类字段就是类属性:通过类来获取

    类字段是声明在类中,函数外面的变量

        class Person:
            '''人类'''
            # 这个person_num就是一个类字段
            person_num = 0
            # 类字段要通过类来使用
            print(Person.person_num)
    

    2.类方法:通过类调用的方法

    开发中怎么确定声明成对象方法还是类方法:看实现的功能是否需要对象属性来支持,如果需要就必须申明成对象方法
    注意:类方法不管是类还是对象都可以调用,实际开发的时候类方法就必须用类调用。
    步骤:
    1.@classmethod来说明下面的函数是类方法
    2.所有的类方法都有一个默认参数cls,这个参数不需要传参,系统会自动将调用方法的类传给它

         class Person:
             '''人类'''
            @classmethod
            def hurt_earth(cls):
                print(cls)
                print('人类破坏环境,伤害地球',Person.person_num,cls.person_num)
    
        Person.hurt_earth()
        print(Person)
    

    练习: 写一个数学类,提供数据的加,减,乘,除的功能

        class Math:
                """实现数据的加"""
            @classmethod
            def add(cls,*num):
                sum1 = 0
                for item in num:
                    sum1 += item
                return sum1
    
        sum1 = Math.add(1,2,34,5)
        print(sum1)
    

    四十五、静态方法

    静态函数:在类中声明,由类来调用的方法
    实例一:静态方法

        class Math:
            """数学类"""
    
            # multiply就是一个静态方法
            @staticmethod
            def multiply(num1,num2):
                return num1 *num2
    
        # 静态方法需要使用类来调用
        print(Math.multiply(10,4))
    

    实例二:静态方法和类方法的区别

    静态方法和类方法都是通过类来调用

    区别:

    1. 类方法都有一个默认参数cls指向调用方法的类,但是静态方法没有

    2. 类型不一样,静态方法的类型是function,类方法的类型是method

       class Download:
           """下载类"""
      
           @staticmethod
           def download_image(image_file):
               print('下载%s下的图片'%(image_file))
      
      
           @classmethod
           def download_movie(cls,movie_file):
               print('下载电影:%s'%(movie_file))
      

      类中普通的函数也是通过类来调用(就是一个静态方法)

           def download(num):
               print('aaa',num)
      
      
       Download.download_image('aa/abc.png')
       print(Download.download_image)
      
       Download.download_movie('aa/123.mp4')
       print(Download.download_movie)
      
       print(Download.__dict__)
       print(Download.download(5))
       print(Download.download)
      

    四十六、类的继承

    继承: 继承就是让子类去拥有父类的东西
    子类: 继承者
    父类(超类): 被继承者

    什么时候用继承:
    在写一个类的时候,发现这个类中的部分属性和方法另一个类都有,这个时候就不用去声明这些属性和方法,直接从类中继承就好了

    实例一:怎么继承
    格式:
    class 子类(父类):
    子类的内容

        class Person:
            """人"""
            def __init__(self,name='aaa',age=0):
                self.name = name
                self.age = age
    
    
        class Student(Person):
            pass
    
        stu1 = Student()
        print(stu1.name)
    

    实例二:可以继承哪些东西?
    1.公开的属性可以继承
    2.私有的属性不可以继承
    3.公开的对象方法可以继承,私有的不行
    4.类的字段可以继承
    5.类的方法和静态也可以继承

    总结:除了私有的其他的都可以继承,slots是不能继承的

        class Animal:
            # 对象的属性
            __slots__ = ('name','__age')
            def __init__(self,name='bb'):
                self.name = name
                self.__age = 18
    
            def run(self):
                print(self.__age)
    
            # 对象方法
            def eat(self):
                print('吃东西')
    
            # 私有的对象方法,只能类的内部才能调用
            def __shout(self):
                print("叫")
    
            # 类字段
            count = 100
            # 类方法
            @classmethod
            def class_func(cls):
                print('class_func')
            # 静态方法
            @staticmethod
            def static_func():
                print('static_func')
    
    
        class Dog(Animal):
    
              def eat_bone(self):
                print('吃骨头')
    
        dog1 = Dog()
        dog1.eat()
        print(Dog.count)
        Dog.class_func()
        Dog.static_func()
    
        dog1.color = 'red'
        print(dog1.color)
    

    四十七、类的继承重写

    声明一个类,如果不声明其父类,那么这个类默认继承自object这个类。
    object类是python中所有类直接或者间接的父类。

        class Aniaml(object):
    
            def __init__(self,name):
                  self.name = name
    
            def shout(self):
                  print('%s嗷嗷叫'%(self.name))
    
            def be_beat(self):
                  print(self.name,'在跑')
                  print('跑的时候嗷嗷叫')
    

    示例一:什么是重写

    重新实现从父类继承下来的方法

        # noinspection PyCompatibility
        class Dog(Aniaml):
    
            # 重写父类的shout方法。然后通过Dog对象调用shout执行的是子类的方法。
            def shout(self):
                  print('%s汪汪叫'%(self.name))
    
            # 重写父类的be_beat,保留了父类实现的功能,并且添加了新的功能
              def be_beat(self):
                # super()指的就是父类的对象
                super().be_beat()
                print('然后奋起反抗,汪汪叫')
    
        dog1 = Dog('大黄')
        dog1.shout()
        dog1.be_beat()
    

    示例二:init示例的继承和重写

        class Person:
            """人"""
            def __init__(self,name='',age=0):
                self.name = name
                self.age = age
    
    
        # noinspection PyCompatibility
        class Student(Person):
            """学生类"""
    

    重写init方法要注意:
    1.如果需要继承父类的对象属性,就需要通过super().init去保留父类的对象属性。然后再添加新的属性。

    def __init__(self,name='bb',age=0,study_id=''):
        super().__init__(name,age)
        self.study_id = study_id
    stu1 = Student()
    print(stu1.name)
    stu2 = Student(study_id='001')
    

    练习:
    写一个正方形类,拥有方法:求面积,求周长 拥有的属性是边长
    写一个长方形类,拥有方法:求面积,求周长 拥有的属性是长和宽

    class Rectangle:
    """长方形类"""
    def __init__(self,a=5,b=10):
        self.a = a
        self.b = b
    
    def area(self):
        return self.a * self.b
    
    def perimeter(self):
        return 2 * (self.a + self.b)
    
    class Quare(Rectangle):
    '''正方形类'''
    def __init__(self):
        super().__init__()
        self.a = self.b
    
    class Rect:
    """长方形类"""
    
    def __init__(self, length=5, width=10):
        self.length = length
        self.width = width
    
    def area(self):
        return self.length * self.width
    
    def perimeter(self):
        return 2 * (self.length + self.width)
    
    
    class Square(Rect):
    '''正方形类'''
    
    def __init__(self,length = 0,width = 0,side = 0):
        super().__init__(length, width)
        self._side = 0
    
    @property
    def side(self):
        return self._side
    
    @side.setter
    def side(self,side):
        self.length = side
        self.width = side
        self._side = side
    
    s1 = Square()
    s1.side = 10
    print(s1.area())
    print(s1.perimeter())
    

    相关文章

      网友评论

          本文标题:Python学习总结【连载】(十三)

          本文链接:https://www.haomeiwen.com/subject/rtvcuftx.html