在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改:

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 来限制类属性的外部更改相关推荐

  1. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感...

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

  2. Python使用property函数为类创建管理方法属性

    1.如何创建可管理的对象属性? 实际案例: 在面向对象编程中,我们把方法(函数)看作对象的接口,直接访问对象的属性可能是不安全的,或设计上不够灵活.但是使用调用方法在形式上不如访问属性简洁. # 创建 ...

  3. python学习高级篇(part1)--类属性

    学习笔记,仅供参考,有错必纠 学习资源:图解python 文章目录 类属性 举个例子 举个例子 类属性 类属性指的是类对象所绑定的属性. 绑定类属性(给类对象绑定属性)的方式有两种: 在类对象的内部( ...

  4. Python用@property使类方法像属性一样访问

    class Screen(object):@property #读取with的值getter方法def width(self):return self._width@width.setter #设置w ...

  5. python 中 property 属性的讲解及应用

    Python中property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回 property属性的有两种方式: 装饰器 即:在方法上应用装饰器 类属性 即:在类中定义 ...

  6. Python 进阶_OOP 面向对象编程_类属性和方法

    目录 目录 类属性 调用类属性 查看类属性 特殊的类属性 类方法 真构造器 __new__ 类属性 在理解类属性之前要先搞清楚 实例属性 和 函数属性 之间的区别: 1. 实例属性:指的是实例化类对象 ...

  7. python 添加类属性

    类属性必须赋值. 创建类属性 类是模板,而实例则是根据类创建的对象.绑定在一个实例上的属性不会影响其他实例,但是,类本身也是一个对象,如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实 ...

  8. python的实例属性和静态属性表_Python:类属性,实例属性,私有属性与静态方法,类方法,实例方法...

    类属性可以直接在方法中赋值,但 一.调用该属性时,必须先调用该方法: 二.与 init 方法区别是,init方法只初始化一次,初始化完成后作为全局变量.在方法中赋值属性,每次调用该方法,该属性初始化一 ...

  9. Python高级——property属性

    property属性 1.property属性: 是一个提高开发者用户体验度的属性,可以将一个函数改造的像属性一样. 例: # 定义的时候像是一个函数 使用的时候和属性的方式是以样的 class Fo ...

最新文章

  1. 关于loader加载的东西必须是继承sprite
  2. C++ 对象内存布局 (4)
  3. Centos 6.4使用本地yum源
  4. SAP Cloud for Customer根据模型某字段进行OData的搜索操作
  5. python如何将utf-8编码文件改为ansi编码文件_Excel导入CSV文件乱码?两个小方法让文件正常显示...
  6. Android之动画精讲一:从setTranslationX谈属性动画和view动画的区别
  7. Zookeeper Watch监听
  8. 直接保存 DataFrame 表格到本地,这个“骚操作”你还不知道?
  9. Android Q安全锁屏下进入google photos不弹bouncer界面
  10. 下一代数据架构Data Fabric到底是什么?
  11. SpringMVC使用websocke
  12. java hypot_Java StrictMath hypot()方法
  13. MATLAB/ArcGIS读取nc数据并进行可视化
  14. python新闻内容爬虫专用包newspaper详细教程
  15. setTimeout 实现 setInterval
  16. 响ASO优化的九大因素
  17. 基于JAVA图书馆座位预约管理系统计算机毕业设计源码+数据库+lw文档+系统+部署
  18. 算法问题:什么是P问题、NP问题和NPC问题zz
  19. nodejs+vue+elementui社区医院挂号管理系统python
  20. 【c++基础】第二章 微观部分:面向对象之类的组成

热门文章

  1. php网站后台管理反应慢,phpcmsv9 后台操作反应慢的原因
  2. python在实际中的作用_Python面向对象中__init__的实际作用是什么?
  3. app导出excel_Excel教程:Excel_VBA你给我走开!
  4. sql和python还有c语言_Python语言之原生sql整理
  5. 中国有替代w ndows的产品吗,电信将引入多款Wndows Phone手机 打造年轻品牌“飞Young”...
  6. c语言中定义结构体指针的作用,c语言定义结构体指针
  7. git pull 报错:权限不够 Permission denied (publickey)
  8. 微信小程序之设置不同的顶部导航栏名称
  9. 字节跳动内部学习资料泄露!kafka入门教程
  10. 【迁移学习(Transfer L)全面指南】零次学习(Zero-Shot Learning)入门