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

>>> class Student(object):
... pass
...
>>> s=Student()
>>> s.score=999
>>> s.score
999
>>> s.score='abc'
>>> s.score
'abc'

  这显然不会逻辑,为了现在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.set_score(100)
>>> s.get_score()
100
>>> s.set_score(101)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in set_score
ValueError: score must between 0~100!

  但是,上面的调用方法比较复杂,有没有直接用属性这么直接减掉

  有没有既能检查参数,又可以有类似属性这样的简单方式来访问类的变量呢。对于类的方法,装饰器一样起作用。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本身又创建了另一个装饰器,负责把一个setter方法变成属性赋值,于是我们就拥有了一个可控的属性操作:

>>> s=Student()
>>> s.score=100
>>> s.score
100
>>> s.score=101
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 18, in score
ValueError: score must between 0~100!

  注意到这个神奇的@property,我们再对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。

  还可以只定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性

class Student(object):
#出生年格式为2001
@property
def birth(self):
return self._birth
@birth.setter
def birth(self,value):
self._birth=value
#年龄age定义为只读即没有setter属性
@property
def age(self):
return 2019-self._birth

  操作

>>> s=Student()
>>> s.birth=2000
#age是根据birth用2019-birth计算出来的
>>> s.age
19
#直接修改age因为没有定义setter使用报错
>>> s.age=20
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

  练习

  利用@property给一个Screen对手加上width和heigth属性,已经一个只读属性resolution  Screen.py

class Screen(object):
#设置长
@property
def width(self):
return self._width
#检查输入是否规范必须是int并且大于0
@width.setter
def width(self,value):
if not isinstance(value,int):
raise ValueError('width must be an integer!')
if value < 0:
raise ValueError('width must > 0')
self._width=value
#设置高
@property
def height(self):
return self._height
@height.setter
def height(self,value):
if not isinstance(value,int):
raise ValueError('height must be an integer!')
if value < 0:
raise ValueError('height must > 0')
self._height=value
#面积只设置getter方法通过长乘高得到
@property
def resolution(self):
return self._width*self._height s=Screen()
s.width=1024
s.height=768
print(s.resolution)

  

Python3之使用@property的更多相关文章

  1. python3 封装之property 多态 绑定方法classmethod 与 非绑定方法 staticmethod

    property 特性 什么是特性property property 是一种特殊的属性,访问它时会执行一段功能(函数),然后返回值 例如 BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而 ...

  2. python3与django中@property详解

    django提供了内置装饰器 @staticmethod\@classmethod\property 在OSQA中,@property的使用频率是非常高的.下面就是它的使用方法: @property ...

  3. python3 - property的使用

    传统的绑定属性值,会把属性暴露出去,而且无法检查参数是否合法,如下: class Test(object): def  __int__(self,age): self.age = age 为了检查参数 ...

  4. python3 高级编程(三) 使用@property

    @property装饰器就是负责把一个方法变成属性调用的. @property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性 cl ...

  5. python3 速查参考- python基础 8 -> 面向对象基础:类的创建与基础使用,类属性,property、类方法、静态方法、常用知识点概念(封装、继承等等见下一章)

    基础概念 1.速查笔记: #-- 最普通的类 class C1(C2, C3): spam = 42 # 数据属性 def __init__(self, name): # 函数属性:构造函数 self ...

  6. Python3.5-20190519-廖老师-自我笔记-面向对象中slots变量--@property的使用

    python是动态语言,可以随时随地给实例对象添加属性和方法,但是我们想限制属性的名字,可以使用__slots__特殊变量来限制 使用__slots__要注意,__slots__定义的属性仅对当前类实 ...

  7. python3(二十七)property

    """ """ __author__ = 'shaozhiqi' # 绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单, # 但是, ...

  8. python3 的setter方法及property修饰

    #!/usr/bin/env pthon#coding:utf-8 class person(object): def __init__(self,name,sex,age,surface,heigh ...

  9. 也说python的类--基于python3.5

    在面向对象的语言中,除了方法.对象,剩下的一大重点就是类了,从意义上来讲,类就是对具有相同行为对象的归纳.当一个或多个对象有相同属性.方法等共同特征的时候,我们就可以把它归纳到同一个类当中.在使用上来 ...

随机推荐

  1. python多线程实现ping多个ip

    #!/usr/bin/env python # -*- coding:utf-8 -*- import subprocess import logging import datetime import ...

  2. js实现图片上传实时显示

    在开发的时候经常遇到这样的需求,用户在上传图片的时候,想要看到自己上传的图片是否正确,这时候需要把用户上传的图片及时显示出来,然后等他点击上传的时候,程序再执行上传到服务器. <!DOCTYPE ...

  3. Java Executor框架使用

    Java Executor框架是Jdk1.5之后推出的,是为了更加方便的开发多线程应用而封装的框架: 相比传统的Thread类,Java Executor使用方便,性能更好,更易于管理,而且支持线程池 ...

  4. SublimeText 括号插件 Bracket Highlighter高亮设置

    1. ctrl + shift + p,打开命令面板,输入install,在菜单中选择Package Control:Install Package如图 2. 步骤1后弹出的命令输入框中 输入:Bra ...

  5. 洛谷 P1076 寻宝 题解

    今天又TM考试了...... 这是T1,然后我模拟20分滚粗. Analysis 在每层的时候用编号%这层可以上楼的房间个数就行了. #include<iostream> #include ...

  6. MongoDB 分片管理(一)检查集群状态

    一.检查集群状态 1.1 使用sh.status()查看集群摘要信息 1.使用sh.status()可以查看分片信息.数据库信息.集合信息 sh.status() 如果数据块较多时,使用sh.stat ...

  7. SpringBoot项目中,Redis的初次使用

    1.引入Redis依赖包,在application.yml中配置redis <dependency> <groupId>org.springframework.boot< ...

  8. P3144 [USACO16OPEN]关闭农场——离线,并查集

    https://www.luogu.org/problem/P3144 每次关闭一个农场,农场之间有边相连,问每次关闭后开着的农场是否是一个连通块: 数据小,离线搞: 我们先记录删的顺序,然后倒着来, ...

  9. Allure自动化测试报告之修改allure测试报告logo

    1.安装allure 2.进入 /usr/local/Cellar/allure/2.10.0/libexec/config 3.在allure.yml添加 - custom-logo-plugin ...

  10. P3975 (后缀自动机sort)

    题目链接: https://www.luogu.org/problem/P3975 题意: 求出所有字串的第k大子串 有两种,第一种对于出现在不同位置的相同子串算作一个子串 第二种,对于不同位置的子串 ...