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实现微信公众平台自定义菜单实例
Mar 20 Python
解决Django模板无法使用perms变量问题的方法
Sep 10 Python
Python2.7+pytesser实现简单验证码的识别方法
Dec 29 Python
python xlsxwriter库生成图表的应用示例
Mar 16 Python
numpy判断数值类型、过滤出数值型数据的方法
Jun 09 Python
Python列表list排列组合操作示例
Dec 18 Python
Python魔法方法详解
Feb 13 Python
使用django和vue进行数据交互的方法步骤
Nov 11 Python
Python&amp;&amp;GDAL实现NDVI的计算方式
Jan 09 Python
python手写均值滤波
Feb 19 Python
python程序输出无内容的解决方式
Apr 09 Python
python opencv肤色检测的实现示例
Dec 21 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判断变量类型常用方法
2012/04/24 PHP
实例讲解PHP面向对象之多态
2014/08/20 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
2014/11/22 PHP
php开发中的页面跳转方法总结
2015/04/26 PHP
php支持断点续传、分块下载的类
2016/05/02 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
2017/08/28 PHP
PHP实现链表的定义与反转功能示例
2018/06/09 PHP
基于laravel缓冲cache的用法详解
2019/10/23 PHP
javascript 新浪背投广告实现代码
2009/07/07 Javascript
测试JavaScript字符串处理性能的代码
2009/12/07 Javascript
javascript中将Object转换为String函数代码 (json str)
2012/04/29 Javascript
javascript时间自动刷新实现原理与步骤
2013/01/06 Javascript
用js控制组织结构图可以任意拖拽到指定位置
2014/01/17 Javascript
jQuery取id有.的值的方法
2014/05/21 Javascript
javascript模拟post提交隐藏地址栏的参数
2014/09/03 Javascript
js获取页面传来参数的方法
2014/09/06 Javascript
使用jQuery将多条数据插入模态框的实现代码
2014/10/08 Javascript
jquery实现Slide Out Navigation滑出式菜单效果代码
2015/09/07 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(基于jquery)
2015/11/18 Javascript
js 获取元素所有兄弟节点的实现方法
2016/09/06 Javascript
js指定日期增加指定月份的实现方法
2018/12/19 Javascript
微信小程序自定义菜单切换栏tabbar组件代码实例
2019/12/30 Javascript
Python学习之Anaconda的使用与配置方法
2018/01/04 Python
Django框架的中的setting.py文件说明详解
2018/10/15 Python
django中间键重定向实例方法
2019/11/10 Python
python获取网络图片方法及整理过程详解
2019/12/20 Python
Pytorch 卷积中的 Input Shape用法
2020/06/29 Python
Django搭建项目实战与避坑细节详解
2020/12/06 Python
HTML+CSS3模拟心的跳动实例代码
2017/09/05 HTML / CSS
《尊严》教学反思
2014/02/11 职场文书
《水乡歌》教学反思
2014/04/24 职场文书
党员群众路线对照检查材料思想汇报
2014/09/17 职场文书
公司股东出资证明书
2014/11/01 职场文书
植树节新闻稿
2015/07/17 职场文书
2016校本研修培训心得体会
2016/01/08 职场文书
《失物招领》教学反思
2016/02/20 职场文书