Python版本:3.5.2

假如我们有一个Student类,并在其中定义了一个score属性,但是score属性会被显露出去,没办法检查参数,导致成绩可以随意更改:

stu = Student()
stu.score = 9999

这显然是不合逻辑的,为了限制score的范围,可以通过一个set_score()方法来设置成绩,并通过一个get_score()方法来获取成绩,这样的话,就可以实现参数的检查:

class Student(object):

    def get_score(self):
return self._score def 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

调用及结果如下:

调用:

stu = Student()
stu.set_score(99)
print(stu.get_score())
stu.set_score(9999) 结果: 99 Traceback (most recent call last):
stu.set_score(9999)
raise ValueError('score must between 0 ~ 100!')
ValueError: score must between 0 ~ 100!

但是,上面的调用方法又略显复杂,没有直接用属性那么直接简单。

这个问题是可以得到解决的,装饰器可以给函数动态的加上功能,那么对于类方法,一样可以起作用,可以使用@property装饰器将类方法变成属性来调用:

class Student(object):

    @property
def score(self):
return self._score @score.setter
def 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

把一个get方法变成属性,只需要加上@property就可以,此时,@property本身又创建了另一个装饰器@score.setter,负责把set方法也变成属性并可以赋值,之后我们就可以直接对score进行属性的操作并带有参数的检查:

调用:

stu = Student()
stu.score = 99
print(stu.score)
stu.score = 9999 结果: 99 Traceback (most recent call last):
stu.score = 9999
raise ValueError('score must between 0 ~ 100!')
ValueError: score must between 0 ~ 100!

有了这个@property,我们就可以无顾虑的操作类的属性。

如果我们我们在类中只定义了get方法(并用@property装饰),而没有定义set方法,那么这个属性就会变成只读属性。

@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。

Python使用@property装饰类方法的更多相关文章

  1. Python的property装饰器的基本用法

    Python的@property装饰器用来把一个类的方法变成类的属性调用,然后@property本身又创建了另一个装饰器,用一个方法给属性赋值.下面是在类中使用了@property后,设置类的读写属性 ...

  2. python中@property装饰器的使用

    目录 python中@property装饰器的使用 1.引出问题 2.初步改善 3.使用@property 4.解析@property 5.总结 python中@property装饰器的使用 1.引出 ...

  3. Python 利用@property装饰器和property()方法将一个方法变成属性调用

    在创建实例属性时,如果直接把实例属性暴露出去,虽然写起来简单,但是存在一些风险,比如实例属性可以在外部被修改. 为了限制外部操作,可以通过一个set_score()方法来设置成绩,再通过一个get_s ...

  4. python之property、类方法和静态方法

    一.完整的property1.定义一个方法被伪装成属性之后,应该可以执行一个属性的增删改查操作,增加和修改就对应着被setter装饰的方法,删除一个属性对应着被deleter装饰的方法. @prope ...

  5. [转载]Python使用@property装饰器--getter和setter方法变成属性

    原贴:为什么Python不需要getter和setter getter 和 setter在java中被广泛使用.一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和sette ...

  6. 【python】@property装饰器

    Python内置的@property装饰器可以把类的方法伪装成属性调用的方式.也就是本来是Foo.func()的调用方法,变成Foo.func的方式.在很多场合下,这是一种非常有用的机制. class ...

  7. Python面向对象-@property装饰器

    python中,我们可以直接添加和修改属性的值: >>> class Student(object): ... pass ... >>> s = Student() ...

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

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

  9. Python之property装饰器

    参考: http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035600.html http://joy2everyone.iteye.com/ ...

随机推荐

  1. merge and saveorupdate

    首先 saveOrUpdate返回void 也就是什么都不返回 而merge会返回一个对象 merge 在执行session.merge(a)代码后,a对象仍然不是持久化状态,a对象仍然不会被关联到S ...

  2. 机器学习面试--一句话概括传统ML算法

    机器学习过程主要包括:数据的特征提取.数据预处理.训练模型.测试模型.模型评估改进等几部分 传统机器学习算法主要包括以下五类: 回归:建立一个回归方程来预测目标值,用于连续型分布预测 分类:给定大量带 ...

  3. vb WIN32 API获取syslistview行数

    Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal ...

  4. usb协议栈学习笔记

    1.usb 集线器为什么一般都是只有4个扩展口? PC的根集线器可为每个A型连接器提供5V.500mA电源.一个总线供电的外部集线器可为每个端口提供100mA电流.由于USB为为外部集线器电路分配10 ...

  5. 秒杀系统-web

    秒杀系统Web层主要涉及前端交互设计.Restful:url满足Restful设计规范.Spring MVC.bootstrap+jquery这四个方面的开发.秒杀系统的前端交互流程设计如下图6-3所 ...

  6. rand_1tom 产生 rand_1ton

    给定一个等概率随机产生1~M的随机函数rand1ToM如下: public int rand1ToM(int m) { return (int) (Math.random() * m) + 1; } ...

  7. 浅谈ESB中的DataRow、DataSet、DataBag 、DataBox

    1 背景概述 笔者在学习公司产品AEAI ESB 的时候经常需要从数据库获取信息并将数据信息保存到一个结果变量中,为统计分析提供特定格式的数据以及跨数据库同步数据时通常会用到DataRow.DataS ...

  8. Java字符串池(String Pool)深度解析

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 在工作中,String类是我们使用频率非常高的一种对象类型.JVM为了提升性能和减少内存开销,避免字符串的重复创建,其维护了一块特殊的内存 ...

  9. boost::bind 实现原理, 手动实现一个

    template<typename R, typename T, typename A1> class hangj_call { public: hangj_call(R (T::*f_) ...

  10. MANIFEST.MF文件详解

    1. 依赖包是否在classpath中: 2. 资源文件目录是否在classpath中: 3. 主类是否正确: 具体配置参考 maven-jar-plugin 配置 <plugin> &l ...