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中操作字符串之replace()方法的使用
May 19 Python
Python实现股市信息下载的方法
Jun 15 Python
python生成九宫格图片
Nov 19 Python
django orm 通过related_name反向查询的方法
Dec 15 Python
Python安装与基本数据类型教程详解
May 29 Python
浅析Windows 嵌入python解释器的过程
Jul 26 Python
Python any()函数的使用方法
Oct 28 Python
python实现局域网内实时通信代码
Dec 22 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
Apr 14 Python
Python趣味入门教程之循环语句while
Aug 26 Python
Pycharm安装Qt Design快捷工具的详细教程
Nov 18 Python
Python爬虫UA伪装爬取的实例讲解
Feb 19 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项目的方法
2006/10/09 PHP
PHP+MYSQL的文章管理系统(二)
2006/10/09 PHP
Mysql数据库操作类( 1127版,提供源码下载 )
2010/12/02 PHP
PHP页面跳转实现延时跳转的方法
2016/12/10 PHP
PHP fopen函数用法实例讲解
2019/02/15 PHP
tp5框架基于Ajax实现列表无刷新排序功能示例
2020/02/10 PHP
jQuery下通过replace字符串替换实现大小图片切换
2012/05/22 Javascript
js判断上传文件类型判断FileUpload文件类型代码
2014/05/20 Javascript
JavaScript代码判断点击第几个按钮
2015/12/13 Javascript
Javascript之Math对象详解
2016/06/07 Javascript
AngularJs自定义服务之实现签名和加密
2016/08/02 Javascript
基于jQuery实现发送短信验证码后的倒计时功能(无视页面关闭)
2016/09/02 Javascript
AngularJS使用自定义指令替代ng-repeat的方法
2016/09/17 Javascript
Extjs gridpanel 中的checkbox(复选框)根据某行的条件不能选中的解决方法
2017/02/17 Javascript
vue如何从接口请求数据
2017/06/22 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
2018/01/05 Javascript
JSON数据中存在单个转义字符“\”的处理方法
2018/07/11 Javascript
基于JavaScript实现瀑布流布局
2018/08/15 Javascript
详解Webpack-dev-server的proxy用法
2018/09/08 Javascript
150行Node.js实现的dns代理工具
2019/08/02 Javascript
vue实现简单图片上传
2020/06/30 Javascript
基于Python3.6+splinter实现自动抢火车票
2018/09/25 Python
Python3.5运算符操作实例详解
2019/04/25 Python
python 获取等间隔的数组实例
2019/07/04 Python
python web框架Flask实现图形验证码及验证码的动态刷新实例
2019/10/14 Python
Python语法之精妙的十个知识点(装B语法)
2020/01/18 Python
Pandas —— resample()重采样和asfreq()频度转换方式
2020/02/26 Python
浅谈Python中的字符串
2020/06/10 Python
BeautifulSoup中find和find_all的使用详解
2020/12/07 Python
Canvas系列之滤镜效果
2019/02/12 HTML / CSS
海淘母婴商城:国际妈咪
2016/07/23 全球购物
学校学习雷锋活动总结
2014/07/03 职场文书
学党史心得体会
2014/09/05 职场文书
MySQL的安装与配置详细教程
2021/06/26 MySQL
Python采集股票数据并制作可视化柱状图
2022/04/04 Python
关于pytest结合csv模块实现csv格式的数据驱动问题
2022/05/30 Python