python常用的属性和方法(Python进阶之@property动态属性的实现)
python常用的属性和方法
Python进阶之@property动态属性的实现Python 动态属性的概念可能会被面试问到,在项目当中也非常实用,但是在一般的编程教程中不会提到,可以进修一下。
先看一个简单的例子。创建一个 Student 类,我希望通过实例来获取每个学生的一些情况,包括名字,成绩等。成绩只有等到考试结束以后才会有,所以实例化的时候不会给它赋值。
|
class Student: def __init__( self , name): self .name = name self .score = None mike = Student( 'mike' ) |
考试完以后,准备给 mike 打分:
|
mike.score = 999 |
在这里,老师一不小心多打了个 9 ,通常来说打分都是 100 分值,999 是一个非法数据,不应该赋值成功。学生一多,老师打分出现手误的情况肯定会越来越多,所以我们必须想办法修改程序,限制 score 的值必须在 0-100 分。
限制值
我们定义一个方法,如果输入的不是 0-100 的整数,就让程序报错,数据合法,我们就把 score 属性修改成功。
|
def set_score( self , new_score): if not isinstance (new_score, int ): raise ValueError( 'score must be int' ) if 0 < = new_score < = 100 : self .score = new_score return self .score else : raise ValueError( 'score invalid' ) |
这样我们每次需要获取成绩的时候使用 self.score 获取,修改成绩的时候调用函数来修改:
|
mike.set_score( 999 ) |
调用以后会报错,因为 999 是非法数据。注意,这个时候我使用 self.score 还是可以进行设置,而且不报错:
|
self .score = 999 |
这显然是不行的。所以我们要提供一种机制,把 score 变成私有属性,不能让外部访问。很遗憾,python 的私有属性是伪私有。通常我们把 _ 开头的属性叫私有属性,但是这只是一种协议和规定,你看到下划线开头的属性,不要去访问了。你硬要访问,是可以的,python 并不会禁止。
使用 @property 的方式代替。
上面的方法虽然实现了功能,但是改变了属性的使用方式。平常是这样使用的:
|
# 获取属性 a = mike.score # 设置属性 mike.score = 99 @property def score( self ): return self ._score @score .setter def score( self , new_score): if not isinstance (new_score, int ): raise ValueError( 'score must be int' ) if 0 < = new_score < = 100 : self ._score = new_score return self ._score else : raise ValueError( 'score invalid' ) |
动态属性的好处
- 统一了调用方式。self.score = 99 的方式,而不是函数调用的方式。
- _score 我们就不直接去使用了。你要用也可以,不建议。
- 如果我们一个属性只可以读,把 setter 部分注释掉就可以了。
现在我们来完善这个类,添加 birth 属性和年龄属性:
|
from datetime import datetime class Student: def __init__( self , name, birth = 1920 ): self .name = name self ._score = None self .birth = birth self .age = datetime.now().year - self .birth mike = Student( 'mike' ) print (mike.birth) print (mike.age) |
birth 和 age 这两个是可以根据一个求出另外一个的。存在数据冗余问题。
age 属性这样是有问题的。mike 初始化的时候,age 已经被求出来了,如果我在下一年再去访问 age 属性,那他就是个错误的值。可以通过把 age 设成现在的秒数来验证:
|
self .age = datetime.now().second mike = Student( 'mike' ) time.sleep( 5 ) print (mike.age) print (datetime.now().second) |
动态显示
|
@property def age( self ): return datetime.now().year - self .birth |
注意,这里不要去设置 @age.setter ,因为他是动态变化的,你修改了会造成数据不一致,它只能作为一个只读属性。
@property 作用和应用场景:
- @property 优化了属性读取和设置的可读性
- 需要限制属性的特征;
- 只读属性。如果属性只可以读,不可以写,用起来很方便。
- 这个属性根据一个变化的环境动态改变。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。
原文链接:http://www.cnblogs.com/wagyuze/p/10622561.html
- python编辑redis(python使用pipeline批量读写redis的方法)
- 用python制作一个简单的小程序(一个可以套路别人的python小程序实例代码)
- python函数基本操作(Python定义函数功能与用法实例详解)
- python中random库的用法(Python minidom模块用法示例DOM写入和解析XML)
- python的mqtt循环发布(python 发送和接收ActiveMQ消息的实例)
- pythonrequests框架实例(Python requests模块实例用法)
- python虚拟环境和包使用教程(在win10和linux上分别安装Python虚拟环境的方法步骤)
- python常用列表函数和方法(Python enumerate函数功能与用法示例)
- python怎么表示矩阵转置(Python实现的矩阵转置与矩阵相乘运算示例)
- 用python3.5.3实现邮件收发(Python使用POP3和SMTP协议收发邮件的示例代码)
- python3爬虫实例代码(python3通过selenium爬虫获取到dj商品的实例代码)
- python使用什么函数定义匿名函数(Python匿名函数及应用示例)
- python如何遍历列表并提取(Python同步遍历多个列表的示例)
- python爬虫书籍经典(Python利用lxml模块爬取豆瓣读书排行榜的方法与分析)
- python scrapy 框架原理(一步步教你用python的scrapy编写一个爬虫)
- pythonssh登录服务器(对python 通过ssh访问数据库的实例详解)
- 小说 顾瑾岚拿出一套飞行棋,别说你连飞行棋都不会哦(顾瑾岚拿出一套飞行棋)
- 金品公司 界界乐中秋限定飞行棋礼盒 露营藤篮礼盒全新上市(界界乐中秋限定飞行棋礼盒)
- 必看 8月,相比七夕,更需要注意的是这些事(必看8月相比七夕)
- 8月23日11时16分将迎处暑,逐渐进入气象意义上的秋天(8月23日11时16分将迎处暑)
- 花不语 下 如果重来一次的话,你还会这么选择吗(花不语下如果重来一次的话)
- 城市记忆之上海 最难忘的是老弄堂里的市井味道(城市记忆之上海)
热门推荐
- ubuntu下mysql安装教程(Ubuntu 20.04 安装和配置MySql5.7的详细教程)
- ftp主动模式和被动模式设置(FTP主动模式和被动模式区别详解)
- mysql写入效率越来越差(MYSQL大量写入问题优化详解)
- python里字典常用方法(Python使用字典的嵌套功能详解)
- Ext.query与Ext.select 的用法
- easyui datebox的用法
- 织梦dedecms教程(详解各种dedeCMS织梦后台登陆验证码错误或不显示解决方法大全)
- 如何激活ubunturoot账号(欧洲vps安装Ubuntu系统如何设置root登录)
- centos7 apache配置(CentOSLinux下的apache服务器配置与管理方法分享)
- JavaScript生成GUID的方法
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9