zoukankan      html  css  js  c++  java
  • 面向对象【林老师版】:特性(property)(十六)

    一、什么是特性property

    property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

    例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
    体质指数(BMI)=体重(kg)÷身高^2(m)
    EX:70kg÷(1.75×1.75)=22.86
    

    1、实现代码

    class People:
        def __init__(self,name,weight,height):
            self.name=name
            self.weight=weight
            self.height=height
        @property
        def bmi(self):
            return self.weight / (self.height**2)
    
    p1=People('luoahong',55,1.55)
    p2=People('typ',65,1.65)
    p3=People('tyx',15,1.03)
    print(p1.bmi)
    print(p2.bmi)
    print(p3.bmi)

    2、输出结果

    class People:
        def __init__(self,name,weight,height):
            self.name=name
            self.weight=weight
            self.height=height
        @property
        def bmi(self):
            return self.weight / (self.height**2)
    
    p1=People('luoahong',55,1.55)
    p2=People('typ',65,1.65)
    p3=People('tyx',15,1.03)
    print(p1.bmi)
    print(p2.bmi)
    print(p3.bmi)

    例二:圆的周长和面积

    1、实现代码

    import math
    class Circle:
        def __init__(self,radius): #圆的半径radius
            self.radius=radius
    
        @property
        def area(self):
            return math.pi * self.radius**2 #计算面积
    
        @property
        def perimeter(self):
            return 2*math.pi*self.radius #计算周长
    
    c=Circle(10)
    print(c.radius)
    print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
    print(c.perimeter) #同上
    

     2、输出结果

    314.1592653589793
    62.83185307179586
    

     注意:此时的特性area和perimeter不能被赋值

    c.area=3 #为特性area赋值
    '''
    抛出异常:
    AttributeError: can't set attribute
    '''
    

    二、为什么要用property

    将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

    除此之外,看下

    ps:面向对象的封装有三种方式:
    【public】
    这种其实就是不封装,是对外公开的
    【protected】
    这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开
    【private】
    这种封装对谁都不公开
    

      python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现

     1、实现代码

    class People:
        def __init__(self,name):
            self.__name=name
    
        @property
        def name(self):
            # print('getter')
            return self.__name
    
        @name.setter
        def name(self,val):
            # print('setter',val)
            if not isinstance(val,str):
                print('名字必须是字符串类型')
                return
            self.__name=val
    
        @name.deleter
        def name(self):
            print('deleter')
    
            print('不允许删除')
    
    p=People('egon')
    
    # print(p.get_name())
    
    print(p.name)
    
    p.name
    p.name='EGON'
    p.name=123
    print(p.name)
    
    del p.name
    

    2、输出结果:

    egon
    名字必须是字符串类型
    EGON
    deleter
    不允许删除
    

    3、完整注解

    class Foo:
        def __init__(self,val):
            self.__NAME=val #将所有的数据属性都隐藏起来
    
        @property
        def name(self):
            return self.__NAME #obj.name访问的是self.__NAME(这也是真实值的存放位置)
    
        @name.setter
        def name(self,value):
            if not isinstance(value,str):  #在设定值之前进行类型检查
                raise TypeError('%s must be str' %value)
            self.__NAME=value #通过类型检查后,将值value存放到真实的位置self.__NAME
    
        @name.deleter
        def name(self):
            raise TypeError('Can not delete')
    
    f=Foo('egon')
    print(f.name)
    # f.name=10 #抛出异常'TypeError: 10 must be str'
    del f.name #抛出异常'TypeError: Can not delete'
  • 相关阅读:
    deque源码2(deque迭代器、deque的数据结构)
    layui 使用随记
    SQL Server 跨服务器、跨版本使用复制 (2008、2012)
    SQLServer 跨服务器链接 Access数据库
    asp.net发布后其他电脑部署——未能加载文件或程序集 System.Web.Mvc, Version=2.0.0.0, Culture=neutral,
    JQuery 遍历table中的checkbox 并对行数据进行校验
    sql 动态行转列 (2005及以上版本)
    JS读取xml
    MVC 创建Controllers 发生 EntityType has no key defined error
    C# 去除数字中多于的0
  • 原文地址:https://www.cnblogs.com/luoahong/p/9945167.html
Copyright © 2011-2022 走看看