Python 中@property的用法详解


Posted in Python onJanuary 15, 2020

在绑定属性时,如果我们直接把属性赋值给对象,比如:

p = Person()
p.name= 'Mary'

我们先看个详细的例子(注意双下划线name和age定义为私有变量):

class Person(object):
  def __init__(self, name, age):
    self.__name = name
    self.__age = age

  def get_age_fun(self):
     return self.__age

  def set_age_fun(self, value):
    if not isinstance(value, int):
      raise ValueError('年龄必须是数字!')
    if value < 0 or value > 100:
      raise ValueError('年龄必须是0-100')
    self.__age = value

  def print_info(self):
    print('%s: %s' % (self.__name, self.__age))


p = Person('balala',20)
p.__age = 17
print(p.__age) # 17
print(p.get_age_fun()) # 20 表面上看,上面代码“成功”地设置了__age变量 17,但实际上这个__age变量和class内部的__age变量不是一个变量!
# 内部的__age变量已经被Python解释器自动改成了_Person_age,而外部代码给p新增了一个__age变量。 所以调用 get_age_fun输出的是初始值

p.set_age_fun(35)
print(p.get_age_fun()) # 35

print(p.print_info()) # balala: 35

输出:

17
20
35
balala: 35

表面上看,外部代码“成功”地设置了__age变量 17,但实际上这个_age变量和class内部的_age变量不是一个变量!

内部的_age变量已经被Python解释器自动改成了_Person_age,而外部代码给p新增了一个_age变量。 所以调用 get_age_fun输出的是初始值 20

而set_age_fun 通过class内部改变了age变量值,所以最终输出 balala: 35

我们再稍微调整下:

(注意只改变了一个变量名: 原来的私有属性 __age 单下划线为: _age,也可以定义为:age.
解释:以一个下划线开头的实例变量名,比如_age,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当看到这样的变量时,意思是,"虽然可以被访问,但是,请视为私有变量,不要随意访问。")

class Person(object):
  def __init__(self, name, age):
    self.__name = name
    self._age = age

  def get_age_fun(self):
     return self._age

  def set_age_fun(self, value):
    if not isinstance(value, int):
      raise ValueError('年龄必须是数字!')
    if value < 0 or value > 100:
      raise ValueError('年龄必须是0-100')
    self._age = value

  def print_info(self):
    print('%s: %s' % (self.__name, self._age))


p = Person('balala',20)
p._age = 17
print(p._age) # 17
print(p.get_age_fun()) # 这里是17 不再是 20,因为此时_age是全局变量,外部直接影响到类内部的更新值

p.set_age_fun(35)
print(p.get_age_fun()) # 35

print(p.print_info()) # balala: 35

输出:

1 17
2 17
3 35
4 balala: 35

看的出私有和全局的设置

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

有没有可以用类似属性这样简单的方式来访问类的变量呢?必须的,对于类的方法
我们先来看一个稍微改造的例子:(稍后我们再使用Python内置的@property装饰器就是负责把一个方法变成属性调用.)

我们进入正题:看看@property的妙用之处:

class Person(object):
  def __init__(self, name, age):
    self.__name = name
    self.__age = age

  @property
  def get_age_fun(self):
     return self.__age

  @get_age_fun.setter # get_age_fun是上面声明的方法
  def set_age_fun(self, value):
    if not isinstance(value, int):
      raise ValueError('年龄必须是数字!')
    if value < 0 or value > 100:
      raise ValueError('年龄必须是0-100')
    self.__age = value

  def print_info(self):
    print('%s: %s' % (self.__name, self.__age))


p = Person('balala',20)
p.__age = 17
print(p.__age) # 17
print(p.get_age_fun) # 20 注意这里不带()

#p.set_age_fun(35) 注意不能这样调用赋值了
p.set_age_fun = 35 # 这里set_age_fun 就是 声明的函数不带()
print(p.get_age_fun) # 35
print(p.print_info()) # balala: 35

输出:

17
20
35
balala: 35

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python里disconnect UDP套接字的方法
Apr 23 Python
Pyhthon中使用compileall模块编译源文件为pyc文件
Apr 28 Python
分析Python中设计模式之Decorator装饰器模式的要点
Mar 02 Python
python3+mysql查询数据并通过邮件群发excel附件
Feb 24 Python
python绘制简单彩虹图
Nov 19 Python
使用Python向DataFrame中指定位置添加一列或多列的方法
Jan 29 Python
python实现五子棋游戏
Jun 18 Python
Django模板语言 Tags使用详解
Sep 09 Python
使用python 计算百分位数实现数据分箱代码
Mar 03 Python
Python实现查找数据库最接近的数据
Jun 08 Python
Python 在函数上添加包装器
Jul 28 Python
python 调用js的四种方式
Apr 11 Python
Python字符串中删除特定字符的方法
Jan 15 #Python
计算pytorch标准化(Normalize)所需要数据集的均值和方差实例
Jan 15 #Python
pytorch 图像中的数据预处理和批标准化实例
Jan 15 #Python
pytorch实现特殊的Module--Sqeuential三种写法
Jan 15 #Python
python实现删除列表中某个元素的3种方法
Jan 15 #Python
python opencv根据颜色进行目标检测的方法示例
Jan 15 #Python
Python基于Tensor FLow的图像处理操作详解
Jan 15 #Python
You might like
vs中通过剪切板循环来循环粘贴不同内容
2011/04/30 PHP
php制作unicode解码工具(unicode编码转换器)代码分享
2013/12/24 PHP
你可能不知道PHP get_meta_tags()函数
2014/05/12 PHP
一键生成各种尺寸Icon的php脚本(实例)
2017/02/08 PHP
PHP简单实现遍历目录下特定文件的方法小结
2017/05/22 PHP
基于Laravel 5.2 regex验证的正确写法
2019/09/29 PHP
jquery的ajaxSubmit()异步上传图片并保存表单数据演示代码
2013/06/04 Javascript
JS验证控制输入中英文字节长度(input、textarea等)具体实例
2013/06/21 Javascript
枚举的实现求得1-1000所有出现1的数字并计算出现1的个数
2013/09/10 Javascript
event对象获取方法总结在google浏览器下测试
2013/11/03 Javascript
javascript设计模式之工厂模式示例讲解
2014/03/04 Javascript
jquery实现树形菜单完整代码
2015/12/29 Javascript
JQuery ztree带筛选、异步加载实例讲解
2016/02/25 Javascript
javascript时间戳和日期字符串相互转换代码(超简单)
2016/06/22 Javascript
jquery+Jscex打造游戏力度条
2020/09/12 Javascript
JQuery和PHP结合实现动态进度条上传显示
2016/11/23 Javascript
bootstrap的常用组件和栅格式布局详解
2017/05/02 Javascript
Vue路由对象属性 .meta $route.matched详解
2019/11/04 Javascript
js 解析 JSON 数据简单示例
2020/04/21 Javascript
使用typescript快速开发一个cli的实现示例
2020/12/09 Javascript
[03:56]显微镜下的DOTA2第十一期——鬼畜的死亡先知播音员
2014/06/23 DOTA
[00:58]2016年国际邀请赛勇士令状宣传片
2016/06/01 DOTA
研究Python的ORM框架中的SQLAlchemy库的映射关系
2015/04/25 Python
Python使用ntplib库同步校准当地时间的方法
2016/07/02 Python
利用CSS3实现动态的二级三级菜单效果实例源码
2017/01/04 HTML / CSS
突袭HTML5之Javascript API扩展4—拖拽(Drag/Drop)概述
2013/01/31 HTML / CSS
HTML5 SEO优化的一些建议
2020/08/27 HTML / CSS
瑞士香水购物网站:Parfumcity.ch
2017/01/14 全球购物
建筑专业毕业生推荐信
2013/11/21 职场文书
kfc实习自我鉴定
2013/12/14 职场文书
招商业务员岗位职责
2013/12/16 职场文书
语文高效课堂实施方案
2014/05/03 职场文书
机关作风整顿个人整改措施思想汇报
2014/09/29 职场文书
党员群众路线整改措施及今后努力方向
2014/10/28 职场文书
2014年扫黄打非工作总结
2014/12/03 职场文书
html+css实现赛博朋克风格按钮
2021/05/26 HTML / CSS