本文整理自《Effective Python 编写高质量 Python 代码的 59 个有效方法》第 29 条:用纯属性取代 get 和 set 方法。

Python 类 public 属性

首先,python 类中的 public 属性可以实现 setter 和 getter 等工具方法功能,动态修改、获取类中的属性:

class Resistor(object):def __init__(self, ohms):self.ohms = ohmsself.voltage = 0self.current = 0if __name__ == '__main__':r1 = Resistor(50e3)r1.ohms = 10e3r1.ohms += 5e3print(r1.ohms)

修改属性时实现特殊行为

如果想在设置属性的时候实现特殊行为(比如顺带着将相关属性一并更新修改),那么可以改用 @property 修饰器和 setter 方法来做,比如下方继承 Resistor 的子类,在给 voltage 赋值时一并将电流值修改赋值:

class Resistor(object):def __init__(self, ohms):self.ohms = ohmsself.voltage = 0self.current = 0class VoltageResistance(Resistor):def __init__(self, ohms):super().__init__(ohms)self._voltage = 0@propertydef voltage(self):return self._voltage@voltage.setterdef voltage(self, voltage):self._voltage = voltageself.current = self._voltage / self.ohmsif __name__ == '__main__':r2 = VoltageResistance(1e3)print("Before: %5r amps" % r2.current)r2.voltage = 10print("After: %5r amps" % r2.current)

修改属性时做验证限制

为属性指定 setter 方法时,也可以在方法里面做类型验证及数值验证,下方定义了个保证传入电阻始终大于 0 欧姆的类:

class Resistor(object):def __init__(self, ohms):self.ohms = ohmsself.voltage = 0self.current = 0class VoltageResistance(Resistor):def __init__(self, ohms):super().__init__(ohms)self._voltage = 0@propertydef voltage(self):return self._voltage@voltage.setterdef voltage(self, voltage):self._voltage = voltageself.current = self._voltage / self.ohmsclass BoundedResistance(Resistor):def __init__(self, ohms):super().__init__(ohms)@propertydef ohms(self):return self._ohms@ohms.setterdef ohms(self, ohms):if ohms <= 0:raise ValueError("%f ohms must be > 0" % ohms)self._ohms = ohmsif __name__ == '__main__':r3 = BoundedResistance(1e3)print(r3.ohms)r3.ohms = 0

运行结果:

ValueError: 0.000000 ohms must be > 0
1000.0

防止父类属性被修改

class Resistor(object):def __init__(self, ohms):self.ohms = ohmsself.voltage = 0self.current = 0class FixedResistance(Resistor):def __init__(self, ohms):super().__init__(ohms)@propertydef ohms(self):return self._ohms@ohms.setterdef ohms(self,ohms):if hasattr(self,"_ohms"):raise AttributeError("Can't set attribute")self._ohms = ohmsif __name__ == '__main__':r4 = FixedResistance(1e3)print(r4.ohms)r4.ohms = 2e3

注意

用 @property 方法实现 setter 和 getter 用法时,不要把程序写得太过奇怪,例如不要再某属性的 getter 方法中去修改其他属性的值,最恰当的方法是只在 @property.setter 里面修改相关的对象状态,并且要防止该对象产生预料之外的副作用。我们所编写的类是要快速修改、返回对象属性,至于比较复杂或速度慢的操作,应该放到普通方法里。

要点

  1. 编写新类,用简单的 public 属性定义接口,不要手工实现 set 和 get
  2. @property 在需要访问对象进行特殊行为时使用,应遵循最小惊讶原则,不应产生奇怪的副作用
  3. @property 方法需要迅速执行,缓慢复杂的工作不要放里面、应该用普通方法来完成

Python @property 用法相关推荐

  1. python的property用法_python @property的用法及含义全面解析

    在接触python时最开始接触的代码,取长方形的长和宽,定义一个长方形类,然后设置长方形的长宽属性,通过实例化的方式调用长和宽,像如下代码一样. class Rectangle(object): de ...

  2. Python高级用法总结

    Python很棒,它有很多高级用法值得细细思索,学习使用.本文将根据日常使用,总结介绍Python的一组高级特性,包括:列表推导式.迭代器和生成器.装饰器. 列表推导(list comprehensi ...

  3. python高级用法技巧-Python高级用法总结

    列表推导(list comprehensions) 场景1:将一个三维列表中所有一维数据为a的元素合并,组成新的二维列表. 最简单的方法:新建列表,遍历原三维列表,判断一维数据是否为a,若为a,则将该 ...

  4. Python pandas用法

    Python pandas用法 无味之味关注 12019.01.10 15:43:25字数 2,877阅读 91,914 介绍 在Python中,pandas是基于NumPy数组构建的,使数据预处理. ...

  5. python goto 用法

    python goto 用法 pip install goto-statement from goto import with_goto @with_goto def range(start, sto ...

  6. Python SQLite 用法

    Python SQLite 用法 具体可以参考网址 代码: #导入 import sqlite3 #连接库,如果数据库不存在,那么它就会被创建,最后将返回一个数据库对象. # test.db:数据路路 ...

  7. import的用法python_Python导入模块,Python import用法(超级详细)

    Python导入模块,Python import用法(超级详细) 使用 Python 进行编程时,有些功能没必须自己实现,可以借助 Python 现有的标准库或者其他人提供的第三方库.比如说,在前面章 ...

  8. python with用法

    @python with用法 python中with可以明显改进代码友好度,比如: [python] view plaincopyprint? with open('a.txt') as f: pri ...

  9. 数据库和python的结合_redis数据库及与python交互用法简单示例

    本文实例讲述了redis数据库及与python交互用法.分享给大家供大家参考,具体如下: redis数据操作 1.string类型:主要存储字符串 操作 命令 设置键值 set key value 设 ...

最新文章

  1. spring cloud快速搭建
  2. Nginx + Spring Boot 实现负载均衡
  3. Android.mk文件语法规范及使用模板 (转载)
  4. 嵌入式LED驱动程序
  5. 车道线检测(opencv)
  6. 我司用了 6 年的 Redis 分布式限流器,很牛逼了!
  7. 自己动手写CPU(2)流水线数据相关问题
  8. 《趣学CCNA——路由与交换》一2.3 网络层协议概述
  9. Codeforces 1091E
  10. css设置 ul的内外边距,9月3日学习CSS选择器,背景设置,及内外边距知识总结
  11. linux-三个文件-用户文件-组文件-密码文件
  12. 文字在图片上c语言,HTML让文字在图片上显示的几种方法
  13. 给Python初学者的入门课程建议
  14. 红帽企业 Linux 下载
  15. jsp java mysql_jsp java mysql
  16. VC2015 运行库安装错误 0x80240017 解决过程
  17. c语言先加后减程序,C语言中的加加减减
  18. 多家波卡生态项目招聘开发者,高薪职位等你来 Pick
  19. 论文:A Real-Time Cross-modality Correlation Filtering Method for Referring Expression Comprehension
  20. 为什么我们不能坚持?

热门文章

  1. 微博年度之夜数据大盘点
  2. PLSQL如何查看建表语句
  3. Matlab色图处理
  4. 京东商品类目如何快速批量迁移?
  5. Python工程师悄悄收藏的Python学习网站
  6. Python3 基础语法介绍
  7. Internet Download Manager2022中文版免费下载
  8. 2022-2027年中国成人服装行业市场深度分析及投资战略规划报告
  9. 基于对比学习的目标检测预训练方法
  10. 安装SQL Server2008的示例数据库AdventureWorks 2008