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

s = Student()
s.score = 9999

  

这显然不合逻辑。为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_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

  

现在,对任意的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):

    @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

  

@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):

    @property
def birth(self):
return self._birth @birth.setter
def birth(self, value):
self._birth = value @property
def age(self):
return 2014 - self._birth

  

上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。

【python】类中@property使用的更多相关文章

  1. 第8章 Python类中常用的特殊变量和方法目录

    第8章 Python类中常用的特殊变量和方法 第8.1节 Python类的构造方法__init__深入剖析:语法释义 第8.2节 Python类的__init__方法深入剖析:构造方法案例详解 第8. ...

  2. Python类中super()和__init__()的关系

    Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...

  3. Python类中的self到底是干啥的

    Python类中的self到底是干啥的 Python编写类的时候,每个函数参数第一个参数都是self,一开始我不管它到底是干嘛的,只知道必须要写上.后来对Python渐渐熟悉了一点,再回头看self的 ...

  4. 【转】python类中super()和__init__()的区别

    [转]python类中super()和__init__()的区别 单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(se ...

  5. 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘

    孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...

  6. Python 简明教程 --- 20,Python 类中的属性与方法

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 与客户保持良好的关系可以使生产率加倍. -- Larry Bernstain 目录 类中的变量称为属 ...

  7. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

  8. 第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析

    第7.17节  Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析 静态方法也是通过类定义的一种方法,一般将不需要访问类属性但是类需要具有的一些能力可以静态方法提供. 一 ...

  9. 第7.14节 Python类中的实例方法详析

    第7.14节 Python类中的实例方法详析 一.    实例方法的定义 在本章前面章节已经介绍了类的实例方法,实例方法的定义有三种方式: 1.    类体中定义实例方法 第一种方式很简单,就是在类体 ...

  10. 第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑

    上节<第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解>通过案例详细分析了两个方法的执行顺序,不知大家是否注意到了,在上述 ...

随机推荐

  1. Informix 11.5 SQL 语句性能监控方法及实现

    我们知道,在数据库应用系统中,SQL 语句的性能好坏至关重要.如果 SQL 语句性能很差,可能会导致整个数据库应用系统的性能也非常差.那么,如何监控数据库系统中 SQL 语句的性能,导致 SQL 语句 ...

  2. three.js

    webgl,three.js交流的论坛,欢迎到里面提问问题 www.webglchina.cn

  3. HTML基本知识

    HTML语言:超文本标记语言 基本结构: <html><head><body> <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  4. MVC5 + EF6 入门完整教程一:从0开始

    第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定". 直接讲这些 "约定" 会让人困惑,而且东西太多容易忘记 ...

  5. 存储过程实现登录(.net)

    工作中,可能有时为了安全等的考虑,需要更多 的运用存储过程.有的公司甚至在登录一栏也会提出这样的要求,那么怎么用存储过程实现登录呢.好处就不用言名了,一个速度,一个就是安全系统更高. 下面贴上:1.存 ...

  6. [强连通分量] POJ 2762 Going from u to v or from v to u?

    Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17089 ...

  7. 运放——压摆率SR的意义和如何选取

    http://blog.csdn.net/dxshappy/article/details/8065798

  8. Hadoop学习资料

    转自:http://cloud21.iteye.com/blog/607175 第一手资源 hadoop官方网站 hadoop.apache.org 最权威的官方资源之一 dev.yahoo.hado ...

  9. CSS3-Media Query 基础

    一.常见的属性: device-width , device-height 屏幕宽高 width , height 渲染窗口宽高 orientation 设备方向 resolution 设备分辨率 二 ...

  10. rpm软件包管理

    RPM 有五种基本的操作方式(不包括创建软件包): 安装, 卸载, 升级, 查询,和验证. 下面我们就来逐一的讲解吧. 一. 安装RPM包 RPM 软件包通常具有类似foo-1.0-1.i386.rp ...