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连接池实现示例程序
Nov 26 Python
Python实现全局变量的两个解决方法
Jul 03 Python
Python语法快速入门指南
Oct 12 Python
详谈Python高阶函数与函数装饰器(推荐)
Sep 30 Python
使用python进行拆分大文件的方法
Dec 10 Python
django中瀑布流写法实例代码
Oct 14 Python
基于python的itchat库实现微信聊天机器人(推荐)
Oct 29 Python
Python如何实现小程序 无限求和平均
Feb 18 Python
python 数据分析实现长宽格式的转换
May 18 Python
python多线程semaphore实现线程数控制的示例
Aug 10 Python
Python pysnmp使用方法及代码实例
Aug 24 Python
Python描述数据结构学习之哈夫曼树篇
Sep 07 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
用ADODB来让PHP操作ACCESS数据库的方法
2006/12/31 PHP
Symfony2 session用法实例分析
2016/02/04 PHP
PDO的安全处理与事物处理方法
2016/10/31 PHP
ThinkPHP 模板substr的截取字符串函数详解
2017/01/09 PHP
php curl上传、下载、https登陆实现代码
2017/07/23 PHP
基于php编程规范(详解)
2017/08/17 PHP
JavaScript实现页面实时显示当前时间的简单实例
2013/07/20 Javascript
返回页面顶部top按钮通过锚点实现(自写)
2013/08/30 Javascript
禁用JavaScript控制台调试的方法
2014/03/07 Javascript
javascript中声明函数的方法及调用函数的返回值
2014/07/22 Javascript
JS验证IP,子网掩码,网关和MAC的方法
2015/07/02 Javascript
自己封装的一个简单的倒计时功能实例
2016/11/23 Javascript
微信小程序 基础组件与导航组件详细介绍
2017/02/21 Javascript
详解Angular-cli生成组件修改css成less或sass的实例
2017/07/27 Javascript
JS实现移动端整屏滑动的实例代码
2017/11/10 Javascript
深入浅析angular和vue还有jquery的区别
2018/08/13 jQuery
ajax与jsonp的区别及用法
2018/10/16 Javascript
JavaScript this关键字指向常用情况解析
2020/09/02 Javascript
python使用rabbitmq实现网络爬虫示例
2014/02/20 Python
Python爬取网易云音乐上评论火爆的歌曲
2017/01/19 Python
六行python代码的爱心曲线详解
2019/05/17 Python
Python Django框架实现应用添加logging日志操作示例
2019/05/17 Python
Win10下用Anaconda安装TensorFlow(图文教程)
2020/06/18 Python
python 窃取摄像头照片的实现示例
2021/01/08 Python
英国虚拟主机服务商:eUKhost
2016/08/16 全球购物
Expedia挪威官网:酒店、机票和租车
2018/03/03 全球购物
阿巴庭院:Abba Patio
2019/06/18 全球购物
污水厂厂长岗位职责
2014/01/04 职场文书
竞选大队长演讲稿
2014/04/29 职场文书
安全生产大检查方案
2014/05/07 职场文书
优秀毕业生找工作自荐信
2014/06/23 职场文书
2015年志愿者服务工作总结
2015/04/20 职场文书
2015年乡镇人大工作总结
2015/04/22 职场文书
小学庆六一主持词
2015/06/30 职场文书
elementui的el-popover修改样式不生效的解决
2021/06/30 Javascript
Go语言并发编程 sync.Once
2021/10/16 Golang