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

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程序员来说,这是必须要做到的!

还记得装饰器可以给函数动态加上功能吗?对于类的方法,装饰器一样起作用,python内置的@propert装饰器就是负责把一个方法变成属性调用:

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 2015 - self._birth

@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查。

class Goods:
__discount = 0.8
def __init__(self,name):
self.name = name
self.__price = 100 @property #将一个方法变成属性
def price(self):
return self.__price * Goods.__discount @price.setter
def price(self,new_price):
self.__price = new_price @price.deleter
def price(self):
del self.__price apple = Goods('苹果')
print(apple.price) #原本是apple.price()
apple.price = 200 #有=就可以关联到属性,原本是不能访问的,因为隐藏了
print(apple.price)
# del apple._Goods__price
del apple.price #del会关联到deleter
# print(apple.price)

如果没有@property就没有下面的setter和delete。

class Foo:
@property
def AAA(self): #AAA已经变成了属性
print("get的时候运行我") @AAA.setter #现在我想修改或重赋值AAA的属性,就可以关联到这里
def AAA(self,value):
print("set的时候运行我") @AAA.deleter #我想删除属性的时候,出现删除的命令的时候就会关联到这
def AAA(self):
print("delete的时候运行我") f1 = Foo()
f1.AAA
f1.AAA = 'aaa'
del f1.AAA 结果:
get的时候运行我
set的时候运行我
delete的时候运行我

面向对象高级编程——使用@property的更多相关文章

  1. Python实用笔记 (24)面向对象高级编程——使用@property

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

  2. 【Python学习之七】面向对象高级编程——使用@property

    参考来自廖雪峰Python教程:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/ ...

  3. C++面向对象高级编程(九)Reference与重载operator new和operator delete

    摘要: 技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一 Reference 引用:之前提及过,他的主要作用就是取别名,与指针很相似,实现也是基于指针. 1.引用必须有初值,且不能引用nul ...

  4. C++面向对象高级编程(八)模板

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 这节课主要讲模板的使用,之前我们谈到过函数模板与类模板 (C++面向对象高级编程(四)基础篇)这里不再说明 1.成员模板 成员模板:参数为tem ...

  5. C++面向对象高级编程(七)point-like classes和function-like classes

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.pointer-like class 类设计成指针那样,可以当做指针来用,指针有两个常用操作符(*和->),所以我们必须重载这两个操作 ...

  6. C++面向对象高级编程(六)转换函数与non-explicit one argument ctor

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.conversion function 转换函数 //1.转换函数 //conversion function //只要你认为合理 你可以任 ...

  7. C++面向对象高级编程(五)类与类之间的关系

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 本节主要介绍一下类与类之间的关系,也就是面向对象编程先介绍两个术语 Object Oriented Programming   OOP面向对象编 ...

  8. C++面向对象高级编程(四)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一.Static 二.模板类和模板函数 三.namespace 一.Static 静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“ ...

  9. C++面向对象高级编程(三)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 一.拷贝构造 二.拷贝赋值 三.重写操作符 四.生命周期 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主 ...

随机推荐

  1. 机器学习经典算法具体解释及Python实现--线性回归(Linear Regression)算法

    (一)认识回归 回归是统计学中最有力的工具之中的一个. 机器学习监督学习算法分为分类算法和回归算法两种,事实上就是依据类别标签分布类型为离散型.连续性而定义的. 顾名思义.分类算法用于离散型分布预測, ...

  2. python-class(3)

    #!/usr/bin/env python #-*- coding:utf-8 -*- ############################ #File Name: class3.py #Auth ...

  3. linux跨主机复制文件

    scp -r billing@10.200.171.111:/billdata2/user/yanhm/redis/* /newboss/billing/user/aabb 其中: 10.200.17 ...

  4. iOS 学习笔记六 【APP中的文字和APP名字的国际化多语言处理】

    今天为新手解决下APP中的文字和APP名字的国际化多语言处理, 不多说了,直接上步骤: 1.打开你的项目,单机project名字,选中project,直接看图吧: 2.创建Localizable.st ...

  5. Android中使用HttpClient发送Get请求

    这里要指定编码,不然服务器接收到的会是乱码的.

  6. JS判断不同的浏览器,不同的浏览器版本

    JS判断不同的浏览器,不同的浏览器版本

  7. Android开发教程:shape和selector的结合使用(转载)

    shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector.可以这样说,shape和 ...

  8. 集合映射Set(使用xml文件)

    如果持久类具有Set对象,可以在映射文件中使用set元素映射Set集合. set元素不需要索引元素. List和Set之间的区别是: Set只存储唯一的值. 我们来看看我们如何在映射文件中实现集合: ...

  9. poj 2594(可相交的最小路径覆盖)

    题目链接:http://poj.org/problem?id=2594 思路:本来求最小路径覆盖是不能相交的,那么对于那些本来就可达的点怎么处理,我们可以求一次传递闭包,相当于是加边,这样我们就可以来 ...

  10. flask session 使用默认配置修改session不生效问题

    flask session相关 使用flask 默认sessio是存储在浏览器的cookie中,当请求返回时会将session写在cooKie中,但是在写的时候,默认并不是每次都重新写入 比如下例子 ...