面向对象【林老师版】:特性(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'
面向对象【林老师版】:特性(property)(十六)的更多相关文章
- 201871010106-丁宣元 《面向对象程序设计(java)》第十六周学习总结
201871010106-丁宣元 <面向对象程序设计(java)>第十六周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://home.cnblogs.com/u/nw ...
- 马凯军201771010116《面向对象与程序设计Java》第十六周知识学习总结
一:理论知识部分 1.线程的概念: 程序是一段静态的代码,它是应用程序执行的蓝 本. ‐进程是程序的一次动态执行,它对应了从代码加 载.执行至执行完毕的一个完整过程. 多线程是进程执行过程中产生的多条 ...
- 201771010134杨其菊《面向对象程序设计(java)》第十六周学习总结
第十六周学习总结 第一部分:理论知识 1. 程序是一段静态的代码,它是应用程序执行的蓝本.进程是程序的一次动态执行,它对应了从代码加载.执行至执行完毕的一个完整过程.操作系统为每个进程分配一段独立的内 ...
- 面向对象【林老师版】:面向过程vs面向对象(一)
一.面向过程 1.引子 面向过程:核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式优点:复杂的问题流程化,进而简单化缺点:可扩展性差 2.验证代码 import json i ...
- 面向对象【林老师版】:__init__定制自己独有的特征(三)
本节内容 1.是如何产生对象 2.实例化的步骤 3.类即类型 一.是如何产生对象? __init__方法用来为对象定制对象自己独有的特征 1.stu1=LuffyStudent()调用报错 1.代码 ...
- 类的加载、时机、反射、模板设计、jdk7/jdk8新特性(二十六)
1.类的加载概述和加载时机 * A:类的加载概述 * 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. * 加载 * 就是指将class文 ...
- 201771010128王玉兰《面向对象程序设计(Java)》第十六周学习总结
第一部分:理论基础 1.线程的概念 进程:进程是程序的一次动态执行,它对应了从代码加 载.执行至执行完毕的一个完整过程. 多线程:多线程是进程执行过程中产生的多条执行线索. 线程:线程是比进程执行 ...
- python cookbook第三版学习笔记十六:抽象基类
假设一个工程中有多个类,每个类都通过__init__来初始化参数.但是可能有很多高度重复且样式相同的__init__.为了减少代码.我们可以将初始化数据结构的步骤归纳到一个单独的__init__函数中 ...
- 201871010133-赵永军《面向对象程序设计(java)》第十六周学习总结
201871010133-赵永军<面向对象程序设计(java)>第十六周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
随机推荐
- LIRE图片识别搜索demo--Ubuntu开发
Ubuntu安装shadowsocks客户端/服务端教程 1.安装shadowsocks sudo apt-get update sudo apt-get install python-pip sud ...
- .net mvc 基类属性覆盖问题
一,问题是这样的 我使用.net mvc设计架构时, 为了方便大家的获取UserInfo信息, 把UserInfo对象,放在了自定义的基类BaseController中, 二,问题出现了 我发觉多个人 ...
- LOJ2251 [ZJOI2017] 树状数组【线段树】【树套树】
题目分析: 对于一个$add$操作,它的特点是与树状数组的查询相同,会给$1$到它自己产生影响,而$query$操作则会途径所有包含它的树状数组点.现在$add$操作具有前向性(不会影响之后的点).所 ...
- Spring模块介绍
GroupId ArtifactId 说明 org.springframework spring-beans Beans 支持,包含 Groovy org.springframework spring ...
- MySQL 报错 1055
具体报错 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'exer.student.sid' w ...
- restfull api交互常用状态码
2xx (成功类别) 200 Ok:标准的 HTTP 响应,表示 GET.PUT 或 POST 的处理成功. 201 Created:在创建新实例时,应返回此状态代码.例如,使用 POST 方法创建一 ...
- linux命令:查看系统版本
debian系统 (1) lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debia ...
- 【最短路算法】Dijkstra+heap和SPFA的区别
单源最短路问题(SSSP)常用的算法有Dijkstra,Bellman-Ford,这两个算法进行优化,就有了Dijkstra+heap.SPFA(Shortest Path Faster Algori ...
- shell 中的 ${} 、## 、%% 使用范例
日常使用范例见如下例子: 利用 ${ } 还可针对不同的变数状态赋值 (沒设定.空值.非空值): ${file-my.file.txt} :假如 $file 沒有设定,則使用 my.file.txt ...
- Nagios 使用 NSClient++ 监控Windows Server
在被监控的Windows server 主机上安装NSClinet++下载地址:https://www.nsclient.org/download/32bit:http://files.nsclien ...