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 相关文章推荐
ptyhon实现sitemap生成示例
Mar 30 Python
python脚本实现统计日志文件中的ip访问次数代码分享
Aug 06 Python
详解Python2.x中对Unicode编码的使用
Apr 03 Python
Python里disconnect UDP套接字的方法
Apr 23 Python
python实现对文件中图片生成带标签的txt文件方法
Apr 27 Python
Pycharm无法显示动态图片的解决方法
Oct 28 Python
Python编程深度学习绘图库之matplotlib
Dec 28 Python
python地震数据可视化详解
Jun 18 Python
django框架使用views.py的函数对表进行增删改查内容操作详解【models.py中表的创建、views.py中函数的使用,基于对象的跨表查询】
Dec 12 Python
python 连续不等式语法糖实例
Apr 15 Python
Python更换pip源方法过程解析
May 19 Python
python 自定义异常和主动抛出异常(raise)的操作
Dec 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
php 正则 过滤html 的超链接
2009/06/02 PHP
php数组合并array_merge()函数使用注意事项
2014/06/19 PHP
WordPress 插件——CoolCode使用方法与下载
2007/07/02 Javascript
javascript实现的距离现在多长时间后的一个格式化的日期
2009/10/29 Javascript
统计出现最多的字符次数的js代码
2010/12/03 Javascript
jQuery设置与获取HTML,文本和值的简单实例
2014/02/26 Javascript
node.js中的fs.mkdirSync方法使用说明
2014/12/17 Javascript
Javascript中arguments用法实例分析
2015/06/13 Javascript
JavaScript如何禁止Backspace键
2015/12/02 Javascript
关于vue.js v-bind 的一些理解和思考
2017/06/06 Javascript
在Vue组件中使用 TypeScript的方法
2018/02/28 Javascript
Vue 源码分析之 Observer实现过程
2018/03/29 Javascript
jQuery实现图片上传预览效果功能完整实例【测试可用】
2018/05/28 jQuery
Vue Router去掉url中默认的锚点#
2018/08/01 Javascript
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
2019/03/29 Javascript
Vue CLI3创建项目部署到Tomcat 使用ngrok映射到外网
2019/05/16 Javascript
vue-video-player视频播放器使用配置详解
2020/10/23 Javascript
[06:37]2014DOTA2国际邀请赛 昔日王者渴望重回巅峰
2014/07/12 DOTA
[04:40]2016国际邀请赛中国区预选赛全程TOP10镜头集锦
2016/07/01 DOTA
浅谈python中的面向对象和类的基本语法
2016/06/13 Python
python去掉行尾的换行符方法
2017/01/04 Python
使用 Python 实现微信公众号粉丝迁移流程
2018/01/03 Python
python针对不定分隔符切割提取字符串的方法
2018/10/26 Python
解决python 未发现数据源名称并且未指定默认驱动程序的问题
2018/12/07 Python
python中break、continue 、exit() 、pass终止循环的区别详解
2019/07/08 Python
网易微博Web App用HTML5开发的过程介绍
2012/06/13 HTML / CSS
美国真皮手袋品牌:GiGi New York
2017/03/10 全球购物
IdealFit官方网站:女性蛋白质、补充剂和运动服装
2019/03/24 全球购物
斯洛伐克家具和时尚装饰品购物网站:Butlers.sk
2019/09/08 全球购物
main 主函数执行完毕后,是否可能会再执行一段代码,给出说明
2012/12/05 面试题
sleep()方法和wait()方法的区别是什么
2012/11/17 面试题
市场营销大学生职业规划书
2014/02/25 职场文书
安全生产计划书
2014/05/04 职场文书
汽车4S店前台接待岗位职责
2015/04/03 职场文书
2015年绩效考核工作总结
2015/05/23 职场文书
mysql知识点整理
2021/04/05 MySQL