面向对象【林老师版】:特性(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/ ...
随机推荐
- windows电脑连接蓝牙耳机的正确步骤
前言 我使用的是小米运动蓝牙耳机,操作系统为win7,废话少说直接上教程 是否支持蓝牙功能 按住win+R,打开[运行],输入devmgmt.msc,回车. 只要有Bluetooth 无线电收发器,那 ...
- web scraper——简单的爬取数据【二】
web scraper——安装[一] 在上文中我们已经安装好了web scraper现在我们来进行简单的爬取,就来爬取百度的实时热点吧. http://top.baidu.com/buzz?b=1&a ...
- 为什么Elasticsearch查询变得这么慢了?
参考内容:https://mp.weixin.qq.com/s/RTpBaFpNELQCO6VE0KMfsw
- 洛谷P1501 Tree II
LCT 还是LCT的板子,下放标记和那道线段树2一样,先放乘..之前用char忘记getchar,调了好久... 注意开long long!! #include <bits/stdc++.h&g ...
- 洛谷P2045 K方格取数(算竞进阶习题)
费用流 又是一道网络流的模型,对于这种费用与经过次数有关的边,我们经常把边拆成多条,比如这个题,第一次费用是x,第二次是0,我们就可以先把点拆成入点和出点,入点和出点又连两条边,第一条容量为1,费用为 ...
- SpringMVC 集成Log4j
项目地址:https://github.com/xiaoqiu-duan/DataProject.git 1.添加jar <dependency> <groupId>org.s ...
- 全局最小割Stoer-Wagner算法
借鉴:http://blog.kongfy.com/2015/02/kargermincut/ 提到无向图的最小割问题,首先想到的就是Ford-Fulkerson算法解s-t最小割,通过Edmonds ...
- 「2017 Multi-University Training Contest 1」2017多校训练1
1001 Add More Zero(签到题) 题目链接 HDU6033 Add More Zero 找出最大的k,使得\(2^m-1\ge 10^k\). 直接取log,-1可以忽略不计. #inc ...
- python学习日记(生成器函数进阶)
迭代器和生成器的概念 迭代器 对于list.string.tuple.dict等这些容器对象,使用for循环遍历是很方便的.在后台for语句对容器对象调用iter()函数.iter()是python内 ...
- LGP2801 教主的魔法
题目链接 : P2801 教主的魔法 这是第一次A分块的题 就是模板题了 每个块内排序 每个整块仅需维护整块的修改量 询问操作: 对于边缘块 直接暴力找在[l, r]内 且比给定值大的有几个 对于整块 ...