在定义一个类的时候,有时我们需要获取一个类的属性值,而这个属性值需要经过类中的其他属性运算来获得的。那么很容易,只要我们在类中定义一个方法,并且通过调用方法可以获取到那个需要运算的属性值。那么,问题来了,当有一天需求变了,你需要反向操作你之前实现的类,你需要通过传入那个需要运算得来的值来获取参与运算的属性值。显然,我们需要重新定义很多的函数来获取那些属性值。这样的类是很不友好的,其他人在调用你定义的类,需要做大量的修改。那么有没有什么解决的办法呢?python提供了一样东西:特性(property)。property避免了以上的问题,使得调用类的人只要知道类怎么用就可以了,而不用了解它是怎么实现的。这很好的实现了面向对象语言的封装性。

这样说来还是有点抽象,那么到底怎么用呢?我下面以一个例子说明property的用法。

以购买水果为例

先粘贴一段代码:

class Fruits:
def __init__(self):
self.name = 'apple'
self.percost = 0.5
self.color = 'red'
self.num = 0 def set_money(self,money):
self.num = money/self.percost def get_money(self):
return self.percost*self.num money = property(get_money,set_money)

我定义一个水果类,初始化水果的名称为apple,单个价格(percost)为0.5元,个数(num)为0。我还定义了get_money方法,用于获取付钱的金额

接下来我们实例化fruit,并为num赋值为10,即要买十个苹果,那么我们想获得需要付多少钱的时候,只要通过调用get_money就可以了。但是奇怪的是,我为什么可以通过直接用fruit.money就可以获得实际的付款金额呢?先别急,接下来慢慢解释。我先往下讲。

读者会发现,我还定义了一个set_money函数和类属性money,那么它们究竟有什么用?从property的参数可以知道,有一个是get_money,就会我们上面想获得的付款金额。通过将get_money传入property函数获得结果赋值给money。那么我们就可以在实例对象中直接通过属性(即fruit.money)的形式来获取付款金额了。

那么set_money又有什么用呢?这就是我文章开头所说的,当有一天需求变了,需要对类的实例对象进行反向操作的时候,我们怎么有效减少代码的数量,提高效率。这个set_money可以使我们在通过fruit.money传入付款金额的时候,接下来通过fruit.num来获取购买的苹果数量。是不是很神奇?

具体的代码实现和结果可以看下面我截出来的两张图。

结果:

一个property函数就可以有如此大的威力,即可以正向操作,由可以反向操作。那么它是如何实现的呢?

通过阅读源码,可以知道,property函数其实质上是一个类,传入的参数有4个,即fget,fset,fdel和doc。分别对应于获取属性值,设置属性值,删除属性值和文档字符串。他们一起定义了所谓的描述符协议。

实际上,这个类包含了一些魔法方法,这些魔法方法为_ _set_ _,_ _get_ _,_ _del_ _。分别在类的属性的设置,获取和删除的时候自动调用。那么可以理解,上面我们定义的get_money,set_money方法,其实内部是调用了上面的魔法方法。当我们在设置fruit.num的时候,自动就会调用set_money方法,那么就会返回我自己写的方法的值,即ruturn self.percost * self.num的结果。反过来,我在设置fruit.money的时候,就会自动调用set_money方法,同样通过我定义的方法,获得了水果的个数,即self.num。那么就可以通过fruit.num轻而易举地获得这个计算出来的个数量了。通过将set_money和get_money方法作为参数传入property函数,我们就可以随时获得想要的结果。在不同的情况获取不同的计算值。

特性property是一个强大的函数,虽然它的内部实现原理很简单,但在实际应用中,笔者认为还是很有用处的。就如我上面所说的需求下,用property可以很好地解决一些问题。更多的用途还需要在实践中去慢慢思考和体会。

python特性--property的更多相关文章

  1. python特性property

    通常,访问类和实例属性的时候,将返回所存储的相关值,也就是直接和类(实例的)的__dict__打交道.若果要规范这些访问和设值方式的话, 一种方法是数据描述符,另一种就是python内置的数据描述符协 ...

  2. python 3全栈开发-面向对象之绑定方法(classmethod与staticmethod的区别)、多态、封装的特性property

    一.面向对象绑定方法 一.类中定义的函数分成两大类 1.绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入): 1. 绑定到类的方法:用classmethod装饰器装饰的方法. 为类量身定制 ...

  3. python 中property函数如何实现

    实际上,在python中property(fget,fset,fdel,doc)函数不是一个真正的函数,他其实是拥有很多特殊方法的类. 这特殊类总的很多方法完成了property函数中的所有工作,涉及 ...

  4. Python的property装饰器的基本用法

    Python的@property装饰器用来把一个类的方法变成类的属性调用,然后@property本身又创建了另一个装饰器,用一个方法给属性赋值.下面是在类中使用了@property后,设置类的读写属性 ...

  5. python's @property

    [python's @property] 参考:http://docs.python.org/3/library/functions.html?highlight=property#property

  6. python 中 property 属性的讲解及应用

    Python中property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回 property属性的有两种方式: 1. 装饰器 即:在方法上应用装饰器 2. 类属性 即 ...

  7. python 特性:height-->while

    """ 出题:height 女生找对象 男生在1米-1.5米之间 小强你在哪里? 男生在1.5-1.7米之间 没有安全感 男生在1.7 - 1.8米之间 帅哥 留个电话 ...

  8. python的property属性

    最近看书中关于Python的property()内建函数属性内容时<python核心编程>解释的生僻难懂,但在网上看到了一篇关于property属性非常好的译文介绍. http://pyt ...

  9. python中@property装饰器的使用

    目录 python中@property装饰器的使用 1.引出问题 2.初步改善 3.使用@property 4.解析@property 5.总结 python中@property装饰器的使用 1.引出 ...

随机推荐

  1. HBase——HMaster启动之一(HMaster的构建)

    首先,让我们来到HMaster的main方法.我们今天的流程就从这里开始. 我们需要注意,下图所示的tool的类型就是HMasterCommandLine. 接下来,让我们来到HMasterComma ...

  2. 解决ionic3 android 运行出现Application Error - The connection to the server was unsuccessful

    在真机上启动ionic3打包成的android APK,启动了很久结果弹出这个问题: Application Error - The connection to the server was unsu ...

  3. 使用apidocJs快速生成在线文档

    https://blog.csdn.net/xialei199023/article/details/63251482 https://blog.csdn.net/qq_16142851/articl ...

  4. 【深度学习与TensorFlow 2.0】入门篇

    注:因为毕业论文需要用到相关知识,借着 TF 2.0 发布的时机,重新捡起深度学习.在此,也推荐一下优达学城与 TensorFlow 合作发布的TF 2.0入门课程,下面的例子就来自该课程. 原文发布 ...

  5. springboot与ActiveMQ整合

    前言 很多项目, 都不是一个系统就做完了. 而是好多个系统, 相互协作来完成功能. 那, 系统与系统之间, 不可能完全独立吧? 如: 在学校所用的管理系统中, 有学生系统, 资产系统, 宿舍系统等等. ...

  6. Java中char和String 的深入理解 - 字符编码

    开篇 https://blog.csdn.net/weixin_37703598/article/details/80679376 我们并不是在写代码,我们只是将自己的思想通过代码表达出来! 1 将思 ...

  7. 项目详解2—LVS负载均衡详解

    一.负载均衡集群介绍 1.集群 ① 集群(cluster)技术是一种较新的技术,通过集群技术,可以在付出较低成本的情况下获得在性能.可靠性.灵活性方面的相对较高的收益,其任务调度则是集群系统中的核心技 ...

  8. RabbitMQ 消息中间件

    RabbitMQ 是使用 Erlang 语言开发的消息中间件, 其遵循了高级消息队列协议(Advanced Message Queuing Protocol, AMQP). 与 Kafka 等消息队列 ...

  9. You must reset your password using ALTER USER statement before executing this statement.

    MySQL 5.7之后,刚初始化的MySQL实例要求先修改密码.否则会报错: mysql> create database test; ERROR 1820 (HY000): You must ...

  10. python模块导入细节

    python模块导入细节 官方手册:https://docs.python.org/3/tutorial/modules.html 可执行文件和模块 python源代码文件按照功能可以分为两种类型: ...