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 相关文章推荐
在树莓派2或树莓派B+上安装Python和OpenCV的教程
Mar 30 Python
Python的装饰器模式与面向切面编程详解
Jun 21 Python
Python程序中用csv模块来操作csv文件的基本使用教程
Mar 03 Python
Python 登录网站详解及实例
Apr 11 Python
django中send_mail功能实现详解
Feb 06 Python
Pandas 按索引合并数据集的方法
Nov 15 Python
Python用61行代码实现图片像素化的示例代码
Dec 10 Python
django url到views参数传递的实例
Jul 19 Python
详解Django admin高级用法
Nov 06 Python
Python PyPDF2模块安装使用解析
Jan 19 Python
python实现PCA降维的示例详解
Feb 24 Python
使用Python和百度语音识别生成视频字幕的实现
Apr 09 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递归列出所有文件和目录的代码
2008/09/10 PHP
PHP+ajax 无刷新删除数据
2010/02/20 PHP
PHP下使用CURL方式POST数据至API接口的代码
2013/02/14 PHP
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
php中Socket创建与监听实现方法
2015/01/05 PHP
php基于curl实现随机ip地址抓取内容的方法
2016/10/11 PHP
PHP函数rtrim()使用中的怪异现象分析
2017/02/24 PHP
不错的JS中变量相关的细节分析
2007/08/13 Javascript
详解参数传递四种形式
2015/07/21 Javascript
javascript解决IE6下hover问题的方法
2015/07/28 Javascript
jQuery如何使用自动触发事件trigger
2015/11/29 Javascript
jquery遍历标签中自定义的属性方法
2016/09/17 Javascript
jQuery remove()过滤被删除的元素(推荐)
2017/07/18 jQuery
基于vue中解决v-for使用报红并出现警告的问题
2018/03/03 Javascript
JavaScript数组基于交换的排序示例【冒泡排序】
2018/07/21 Javascript
CryptoJS中AES实现前后端通用加解密技术
2018/12/18 Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
2019/08/20 Javascript
TypeScript高级用法的知识点汇总
2019/12/17 Javascript
通过微信公众平台获取公众号文章的方法示例
2019/12/25 Javascript
vue实现从外部修改组件内部的变量的值
2020/07/30 Javascript
js实现限定范围拖拽的示例
2020/10/26 Javascript
[51:17]Mski vs VGJ.S Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
用Python实现一个简单的能够上传下载的HTTP服务器
2015/05/05 Python
Python检测生僻字的实现方法
2016/10/23 Python
python 生成器生成杨辉三角的方法(必看)
2017/04/10 Python
django获取from表单multiple-select的value和id的方法
2019/07/19 Python
HTML5 本地存储 LocalStorage详解
2016/06/24 HTML / CSS
HTML5中div、article、section的区别及使用介绍
2013/08/14 HTML / CSS
大学生就业推荐信范文
2013/11/29 职场文书
中国央视网签名寄语
2014/01/18 职场文书
文明餐桌活动方案
2014/02/11 职场文书
公司总经理岗位职责
2015/04/01 职场文书
2015年公司中秋节致辞
2015/07/31 职场文书
2016大学先进团支部事迹材料
2016/03/01 职场文书
JS数组的常用方法整理
2021/03/31 Javascript
了解Redis常见应用场景
2021/06/23 Redis