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实现字典去除重复的方法示例
Jul 31 Python
python打包压缩、读取指定目录下的指定类型文件
Apr 12 Python
基于MTCNN/TensorFlow实现人脸检测
May 24 Python
django解决跨域请求的问题详解
Jan 20 Python
在Python中字典根据多项规则排序的方法
Jan 21 Python
基于python实现百度翻译功能
May 09 Python
ubuntu 16.04下python版本切换的方法
Jun 14 Python
在python里面运用多继承方法详解
Jul 01 Python
Python判断三段线能否构成三角形的代码
Apr 12 Python
python实现手势识别的示例(入门)
Apr 15 Python
解决windows上安装tensorflow时报错,“DLL load failed: 找不到指定的模块”的问题
May 20 Python
pytorch 如何使用float64训练
May 24 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
老照片 - 几十年前的收音机与人
2021/03/02 无线电
php获取淘宝分类id示例
2014/01/16 PHP
PHP多进程编程实例
2014/10/15 PHP
php实现获取文章内容第一张图片的方法
2014/11/04 PHP
WordPress中用于获取及自定义头像图片的PHP脚本详解
2015/12/17 PHP
php array_chunk()函数用法与注意事项
2019/07/12 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
2019/11/26 PHP
laravel 框架执行流程与原理简单分析
2020/02/01 PHP
Apache+PHP+MySQL搭建PHP开发环境图文教程
2020/08/06 PHP
JavaScript中使用构造函数实现继承的代码
2010/08/12 Javascript
仿猪八戒网左下角的文字滚动效果
2011/10/28 Javascript
JavaScript数值数组排序示例分享
2014/05/27 Javascript
jQuery简单tab切换效果实现方法
2015/04/08 Javascript
实例代码讲解jquery easyui动态tab页
2015/11/17 Javascript
微信小程序 教程之条件渲染
2016/10/18 Javascript
JavaScript仿微博发布信息案例
2016/11/16 Javascript
jQuery is not defined 错误原因与解决方法小结
2017/03/19 Javascript
Vue2.0 从零开始_环境搭建操作步骤
2017/06/14 Javascript
jQuery实现的鼠标拖动浮层功能示例【拖动div等任何标签】
2018/12/29 jQuery
jQuery中使用validate插件校验表单功能
2019/05/24 jQuery
Angular8 实现table表格表头固定效果
2020/01/03 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
2020/03/23 Javascript
js实现贪吃蛇小游戏(加墙)
2020/07/31 Javascript
[03:21]【TI9纪实】Old Boys
2019/08/23 DOTA
Python 类的特殊成员解析
2018/06/20 Python
Python学习笔记之文件的读写操作实例分析
2019/08/07 Python
如何运行带参数的python脚本
2019/11/15 Python
Python csv文件的读写操作实例详解
2019/11/19 Python
介绍一下linux的文件系统
2015/10/06 面试题
经理管理专业自荐信范文
2013/12/31 职场文书
房产转让协议书
2014/04/11 职场文书
2015年见习期工作总结
2014/12/12 职场文书
市场营销计划书范文
2015/01/16 职场文书
《狼牙山五壮士》教学反思
2016/02/17 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书
世界各国短波电台对东亚播送时间频率表(SW)
2021/06/28 无线电