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装饰器原理与简单用法实例分析
Apr 29 Python
pandas 对series和dataframe进行排序的实例
Jun 09 Python
Python pymongo模块常用操作分析
Sep 01 Python
解析Python的缩进规则的使用
Jan 16 Python
django 连接数据库 sqlite的例子
Aug 14 Python
python3实现微型的web服务器
Sep 03 Python
Python定时发送天气预报邮件代码实例
Sep 09 Python
春节到了 教你使用python来抢票回家
Jan 06 Python
使用python实现飞机大战游戏
Mar 23 Python
Python实现封装打包自己写的代码,被python import
Jul 12 Python
如何使用Pytorch搭建模型
Oct 26 Python
基于pycharm 项目和项目文件命名规则的介绍
Jan 15 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
239军机修复记
2021/03/02 无线电
PHP系列学习之日期函数使用介绍
2012/08/18 PHP
带密匙的php加密解密示例分享
2014/01/29 PHP
PHP安装扩展mcrypt以及相关依赖项深入讲解
2021/03/04 PHP
javascript:history.go()和History.back()的区别及应用
2012/11/25 Javascript
javascript中this做事件参数相关问题解答
2013/03/17 Javascript
Extjs NumberField后面加单位实现思路
2013/07/30 Javascript
jquery mobile事件多次绑定示例代码
2013/09/13 Javascript
简单介绍JavaScript中字符串创建的基本方法
2015/07/07 Javascript
jquery实现动画菜单的左右滚动、渐变及图形背景滚动等效果
2015/08/25 Javascript
JS数组合并push与concat区别分析
2015/12/17 Javascript
BootStrap中的table实现数据填充与分页应用小结
2016/05/26 Javascript
angular+ionic 的app上拉加载更新数据实现方法
2017/01/16 Javascript
微信小程序中的onLoad详解及简单实例
2017/04/05 Javascript
自定义事件解决重复请求BUG的问题
2017/07/11 Javascript
Node.js创建Web、TCP服务器
2017/12/05 Javascript
浅谈Vue2.0父子组件间事件派发机制
2018/01/08 Javascript
AJAX在JQuery中的应用详解
2019/01/30 jQuery
解决Antd 里面的select 选择框联动触发的问题
2020/10/24 Javascript
[03:38]TI4西雅图DOTA2前线报道 71专访
2014/07/08 DOTA
利用Python3分析sitemap.xml并抓取导出全站链接详解
2017/07/04 Python
用pycharm开发django项目示例代码
2018/10/24 Python
python linecache 处理固定格式文本数据的方法
2019/01/08 Python
python打印n位数“水仙花数”(实例代码)
2019/12/25 Python
python 画图 图例自由定义方式
2020/04/17 Python
Python格式化输出--%s,%d,%f的代码解析
2020/04/29 Python
django序列化时使用外键的真实值操作
2020/07/15 Python
Python-split()函数实例用法讲解
2020/12/18 Python
大女孩胸罩:Big Girls Bras
2016/12/15 全球购物
优秀少先队工作者事迹材料
2014/05/13 职场文书
教师演讲稿开场白
2014/08/25 职场文书
标会主持词应该怎么写?
2019/08/15 职场文书
高端收音机+蓝牙音箱,JBL TUNER FM带收音蓝牙音箱评测
2021/04/24 无线电
浅谈Web Storage API的使用
2021/06/23 Javascript
浅谈Redis位图(Bitmap)及Redis二进制中的问题
2021/07/15 Redis
Nginx图片服务器配置之后图片访问404的问题解决
2022/03/21 Servers