python 使用@property 来限制类属性的外部更改
在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改:
s = Student()
s.score = 9999
这显然不合逻辑。为了限制score的范围,可以通过一个set_score()
方法来设置成绩,再通过一个get_score()
来获取成绩,这样,在set_score()
方法里,就可以检查参数:
class Student(object):def get_score(self):return self._scoredef set_score(self, value):if not isinstance(value, int):raise ValueError('score must be an integer!')if value < 0 or value > 100:raise ValueError('score must between 0 ~ 100!')self._score = value
现在,对任意的Student实例进行操作,就不能随心所欲地设置score了:
>>> s = Student()
>>> s.set_score(60) # ok!
>>> s.get_score()
60
>>> s.set_score(9999)
Traceback (most recent call last):...
ValueError: score must between 0 ~ 100!
但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。
有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?对于追求完美的Python程序员来说,这是必须要做到的!
还记得装饰器(decorator)可以给函数动态加上功能吗?对于类的方法,装饰器一样起作用。Python内置的@property
装饰器就是负责把一个方法变成属性调用的:
class Student(object):@propertydef score(self):return self._score@score.setterdef score(self, value):if not isinstance(value, int):raise ValueError('score must be an integer!')if value < 0 or value > 100:raise ValueError('score must between 0 ~ 100!')self._score = value
@property
的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property
就可以了,此时,@property
本身又创建了另一个装饰器@score.setter
,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:
>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):...
ValueError: score must between 0 ~ 100!
注意到这个神奇的@property
,我们在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。
还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:
class Student(object):@propertydef birth(self):return self._birth@birth.setterdef birth(self, value):self._birth = value@propertydef age(self):return 2014 - self._birth
上面的birth
是可读写属性,而age
就是一个只读属性,因为age
可以根据birth
和当前时间计算出来。
小结
@property
广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。
python 使用@property 来限制类属性的外部更改相关推荐
- 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感...
关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...
- Python使用property函数为类创建管理方法属性
1.如何创建可管理的对象属性? 实际案例: 在面向对象编程中,我们把方法(函数)看作对象的接口,直接访问对象的属性可能是不安全的,或设计上不够灵活.但是使用调用方法在形式上不如访问属性简洁. # 创建 ...
- python学习高级篇(part1)--类属性
学习笔记,仅供参考,有错必纠 学习资源:图解python 文章目录 类属性 举个例子 举个例子 类属性 类属性指的是类对象所绑定的属性. 绑定类属性(给类对象绑定属性)的方式有两种: 在类对象的内部( ...
- Python用@property使类方法像属性一样访问
class Screen(object):@property #读取with的值getter方法def width(self):return self._width@width.setter #设置w ...
- python 中 property 属性的讲解及应用
Python中property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回 property属性的有两种方式: 装饰器 即:在方法上应用装饰器 类属性 即:在类中定义 ...
- Python 进阶_OOP 面向对象编程_类属性和方法
目录 目录 类属性 调用类属性 查看类属性 特殊的类属性 类方法 真构造器 __new__ 类属性 在理解类属性之前要先搞清楚 实例属性 和 函数属性 之间的区别: 1. 实例属性:指的是实例化类对象 ...
- python 添加类属性
类属性必须赋值. 创建类属性 类是模板,而实例则是根据类创建的对象.绑定在一个实例上的属性不会影响其他实例,但是,类本身也是一个对象,如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实 ...
- python的实例属性和静态属性表_Python:类属性,实例属性,私有属性与静态方法,类方法,实例方法...
类属性可以直接在方法中赋值,但 一.调用该属性时,必须先调用该方法: 二.与 init 方法区别是,init方法只初始化一次,初始化完成后作为全局变量.在方法中赋值属性,每次调用该方法,该属性初始化一 ...
- Python高级——property属性
property属性 1.property属性: 是一个提高开发者用户体验度的属性,可以将一个函数改造的像属性一样. 例: # 定义的时候像是一个函数 使用的时候和属性的方式是以样的 class Fo ...
最新文章
- 关于loader加载的东西必须是继承sprite
- C++ 对象内存布局 (4)
- Centos 6.4使用本地yum源
- SAP Cloud for Customer根据模型某字段进行OData的搜索操作
- python如何将utf-8编码文件改为ansi编码文件_Excel导入CSV文件乱码?两个小方法让文件正常显示...
- Android之动画精讲一:从setTranslationX谈属性动画和view动画的区别
- Zookeeper Watch监听
- 直接保存 DataFrame 表格到本地,这个“骚操作”你还不知道?
- Android Q安全锁屏下进入google photos不弹bouncer界面
- 下一代数据架构Data Fabric到底是什么?
- SpringMVC使用websocke
- java hypot_Java StrictMath hypot()方法
- MATLAB/ArcGIS读取nc数据并进行可视化
- python新闻内容爬虫专用包newspaper详细教程
- setTimeout 实现 setInterval
- 响ASO优化的九大因素
- 基于JAVA图书馆座位预约管理系统计算机毕业设计源码+数据库+lw文档+系统+部署
- 算法问题:什么是P问题、NP问题和NPC问题zz
- nodejs+vue+elementui社区医院挂号管理系统python
- 【c++基础】第二章 微观部分:面向对象之类的组成
热门文章
- php网站后台管理反应慢,phpcmsv9 后台操作反应慢的原因
- python在实际中的作用_Python面向对象中__init__的实际作用是什么?
- app导出excel_Excel教程:Excel_VBA你给我走开!
- sql和python还有c语言_Python语言之原生sql整理
- 中国有替代w ndows的产品吗,电信将引入多款Wndows Phone手机 打造年轻品牌“飞Young”...
- c语言中定义结构体指针的作用,c语言定义结构体指针
- git pull 报错:权限不够 Permission denied (publickey)
- 微信小程序之设置不同的顶部导航栏名称
- 字节跳动内部学习资料泄露!kafka入门教程
- 【迁移学习(Transfer L)全面指南】零次学习(Zero-Shot Learning)入门