zoukankan      html  css  js  c++  java
  • Python封装补充

    property属性

    property实际是setter getter deleter是集合体,并不是一个单独的方法

    import math  # 使用的库
    
    class Circle:
        def __init__(self,radius): #定义圆的半径
            self.radius = radius
    
        @property   # area = property(area)  #
        def area(self):
            return math.pi * self.radius**2  # 在类内部的函数,返回值
    
        @property
        def peirimeter(self):
            return 2*math.pi*self.radius
    
    c1= Circle(5)  # 对类实例化 产生一个对象
    print(c1.radius)  # 打印的是半径的值
    print(c1.area)    # 这里相当于是直接使用了一个属性,并没有使用绑定方法
    print(c1.peirimeter)
    

    结果:
    5
    78.53981633974483
    31.41592653589793

    注意:
    c.area是不能赋值的,虽然我们能够当做看似通过属性进行调用,实际是不是的

    c1.area = 1
    

    结果是:
    AttributeError: can't set attribute
    会抛出错误

    下面是一个测试:
    print(type(Circle.area)) #此时类是不能使用area函数的,结果是class property
    print(Circle.area) # 结果是property object at 0x00000000006AB5E8

    为什么要用property

    将一个函数的类定义成property特性后,对象使用object.name,无法知道这个name是函数计算出来的,这种特性的使用方式遵循统一访问原则

    面向对象中有三种类:
    public --就是公开类
    protected -- 父类
    private -- 私有类

    但是python的class机制并没有把这三种语法,像C++提供的是set和get方法,Python中是通过property方法提供

    class People:
        def __init__(self,name,SEX):
            self.name = name
            self.__sex = SEX  # 进行封装
    
        @property
        def sex(self):
            return self.__sex  # 这里的返回值是真实的值
    
    p1 = People('aaa','male')
    print(p1.name)  #  雷士通过属性的方式进行了调用
    print(p1.sex)
    

    结果:
    male
    aaa

    通过属性的的方式是通过property的方式能够object.name的方式,这里就是用来实例化的p1.name p1.sex来是实现

    但是这种属性并不是真正的属性,不能通过赋值的方式修改,后期需要进行修改用到了setter方法

    setter方法是用了被property装饰器后的函数名命名了一个新的装饰器

    class People:
        def __init__(self,name,SEX):
            self.name = name
            self.__sex = SEX  # 进行封装
    
        @property
        def sex(self):
            return self.__sex  # 这里的返回值是真实的值
    
        @sex.setter  # 想要对上面得函数属性进行修改
        def sex(self,value):  # value的值是是想要进行修改的参数
            # print('============')  # 测试用
            print(self,value)
            self.__sex = value  # 真实的值是存在与__sex中,赋值给value
    
    p1 = People('aaa','male')   # 实例化
    p1.sex = 'femele'  # 这里就是通过类似赋值的方式进行了修改
    print(p1.sex)   # 新的查看
    

    结果:
    famele

    上面的关键是@sex.setter重新命名了一个新的装饰器,装饰器的名字是sex,它的方法是setter。p1.sex = 'femele' 这这执行的时候首先从property下面的sex.__sex,这里存放的是真实的sex的值,所以的赋值只能在这里

    通过抛出异常,限制输入的参数必须是字符串

    class People:
        def __init__(self,name,SEX):
            self.name = name
            # self.__sex = SEX  # 进行封装
            self.sex = SEX      # 这里直接初始化的时候就会进入@sex.seter
    
        @property
        def sex(self):
            return self.__sex  # 这里的返回值是真实的值
    
        @sex.setter  # 想要对上面得函数属性进行修改
        def sex(self,value):  # value的值是是想要进行修改的参数
            # print('============')  # 测试用
            print(self,value)
            if not isinstance(value,str):  # 判断修改的不是字符串,抛出异常
                raise TypeError("male 必须是字符串类型")
            self.__sex = value  # 真实的值是存在与__sex中,赋值给value
    
    p1 = People('aaa','male')   # 实例化
    p1.sex = 'femele'
    print(p1.sex)
    

    上面的修改是在setter中在修改赋值之前增加了异常处理,如果输入的不是字符串,就会抛出异常,但是这个只是在实例化赋值(p1.sex = 123)时候用才会抛出异常,在类的初始化的时候直接就self.sex=SEX,p1 = People('aaa',123) # 实例化最初的时候就会抛出异常

    删除操作

    class People:
        def __init__(self,name,SEX):
            self.name = name
            # self.__sex = SEX  # 进行封装
            self.sex = SEX
    
        @property
        def sex(self):
            return self.__sex  # 这里的返回值是真实的值
    
        @sex.setter  # 想要对上面得函数属性进行修改
        def sex(self,value):  # value的值是是想要进行修改的参数
            # print('============')  # 测试用
            print(self,value)
            if not isinstance(value,str):  # 判断修改的不是字符串,抛出异常
                raise TypeError("male 必须是字符串类型")
            self.__sex = value  # 真实的值是存在与__sex中,赋值给value
    
        @sex.deleter
        def sex(self):
            del self.__sex   # 同样删除的是真实存放内容的__sex
    
    p1 = People('aaa','male')
    print(p1.sex)
    del p1.sex   # 删除p1的sex属性
    
    
  • 相关阅读:
    yellow joke 3
    JavaScript下拉菜单(1)
    Java程序员面试三十二问
    Oracle里时间的应用
    ·Java读取properties文件
    Web 窗体用户控件
    怎么解决层被flash挡住的问题?
    自定义控件
    关于mysql中的DDL,DML,DQL和DCL
    自定义一个简单连接池以及常见连接池的使用
  • 原文地址:https://www.cnblogs.com/Python666/p/6750500.html
Copyright © 2011-2022 走看看