Python进阶之“属性(property)”详解

来源:http://python.jobbole.com/80955/

参考:廖雪峰的官方网站 使用__slots__

参考:廖雪峰的官方网站 使用 @property

Python中有一个被称为属性函数(property)的小概念,它可以做一些有用的事情。在这篇文章中,我们将看到如何能做以下几点:

  • 将类方法转换为只读属性
  • 重新实现一个属性的setter和getter方法

在本文中,您将学习如何以几种不同的方式来使用内置的属性函数。希望读到文章的末尾时,你能看到它是多么有用。

开始

使用属性函数的最简单的方法之一是将它作为一个方法的装饰器来使用。这可以让你将一个类方法转变成一个类属性。当我需要做某些值的合并时,我发现这很有用。其他想要获取它作为方法使用的人,发现在写转换函数时它很有用。让我们来看一个简单的例子:

########################################################################
class Person(object):""""""#----------------------------------------------------------------------def __init__(self, first_name, last_name):"""Constructor"""self.first_name = first_nameself.last_name = last_name#----------------------------------------------------------------------@propertydef full_name(self):"""Return the full name"""return "%s %s" % (self.first_name, self.last_name)
在上面的代码中,我们创建了两个类属性: self.first_nameself.last_name。接下来,我们创建了一个 full_name方法,它有一个 @property装饰器。这使我们能够在Python解释器会话中有如下的交互:
>>> person = Person("Mike", "Driscoll")
>>> person.full_name
'Mike Driscoll'
>>> person.first_name
'Mike'
>>> person.full_name = "Jackalope"
Traceback (most recent call last):File "<string>", line 1, in <fragment>
AttributeError: can't set attribute
正如你所看到的,因为我们将方法变成了属性,我们可以使用正常的点符号访问它。但是,如果我们试图将该属性设为其他值,我们会引发一个 AttributeError错误。改变 full_name属性的唯一方法是间接这样做:
>>> person.first_name = "Dan"
>>> person.full_name
'Dan Driscoll'

这是一种限制,因此让我们来看看另一个例子,其中我们可以创建一个允许设置的属性。

使用Python property取代setter和getter方法

让我们假设我们有一些遗留代码,它们是由一些对Python理解得不够好的人写的。如果你像我一样,你之前已经看到过这类的代码:

from decimal import Decimal########################################################################
class Fees(object):""""""#----------------------------------------------------------------------def __init__(self):"""Constructor"""self._fee = None#----------------------------------------------------------------------def get_fee(self):"""Return the current fee"""return self._fee#----------------------------------------------------------------------def set_fee(self, value):"""Set the fee"""if isinstance(value, str):self._fee = Decimal(value)elif isinstance(value, Decimal):self._fee = value
要使用这个类,我们必须要使用定义的getter和setter方法​​:
>>> f = Fees()
>>> f.set_fee("1")
>>> f.get_fee()
Decimal('1')
如果你想添加可以使用正常点符号访问的属性,而不破坏所有依赖于这段代码的应用程序,你可以通过添加一个属性函数非常简单地改变它:
from decimal import Decimal########################################################################
class Fees(object):""""""#----------------------------------------------------------------------def __init__(self):"""Constructor"""self._fee = None#----------------------------------------------------------------------def get_fee(self):"""Return the current fee"""return self._fee#----------------------------------------------------------------------def set_fee(self, value):"""Set the fee"""if isinstance(value, str):self._fee = Decimal(value)elif isinstance(value, Decimal):self._fee = valuefee = property(get_fee, set_fee)
我们在这段代码的末尾添加了一行。现在我们可以这样做:
>>> f = Fees()
>>> f.set_fee("1")
>>> f.fee
Decimal('1')
>>> f.fee = "2"
>>> f.get_fee()
Decimal('2')
正如你所看到的,当我们以这种方式使用 属性函数时,它允许fee属性设置并获取值本身而不破坏原有代码。让我们使用属性装饰器来重写这段代码,看看我们是否能得到一个允许设置的属性值。
from decimal import Decimal########################################################################
class Fees(object):""""""#----------------------------------------------------------------------def __init__(self):"""Constructor"""self._fee = None#----------------------------------------------------------------------@propertydef fee(self):"""The fee property - the getter"""return self._fee#----------------------------------------------------------------------@fee.setterdef fee(self, value):"""The setter of the fee property"""if isinstance(value, str):self._fee = Decimal(value)elif isinstance(value, Decimal):self._fee = value#----------------------------------------------------------------------
if __name__ == "__main__":f = Fees()
上面的代码演示了如何为 fee属性创建一个setter方法。你可以用一个名为 @fee.setter的装饰器装饰第二个方法名也为fee的方法来实现这个。当你如下所做时,setter被调用:
>>> f = Fees()
>>> f.fee = "1"

如果你看属性函数的说明,它有fget, fset, fdel和doc几个参数。如果你想对属性使用del命令,你可以使用@fee.deleter创建另一个装饰器来装饰相同名字的函数从而实现删除的同样效果。

结束语

现在你知道如何在你的类中使用Python的属性函数。希望你能找到更有用的方式,在你的代码中使用它们。

补充阅读:

  • Python中的getter和setter方法
  • 官方Python文档中对property的介绍
  • StackOverflow中对给Python属性函数增加文档字符串的一个讨论


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/497087.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

冒泡排序(c++)

冒泡排序&#xff08;Bubble Sort&#xff09; 是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列&#xff0c;依次比较两个相邻的元素&#xff0c;如果顺序&#xff08;如从大到小、首字母从Z到A&#xff09;错误就把他们交换过来。走访元素的工作是重复…

微软研发致胜策略读书笔记(转)

创建人&#xff1a;X公司程序员 yunshichen 这篇是我读《微软研发致胜策略》后整理的笔记。身为一个软件开发部门的主管&#xff0c;你的职责是什么&#xff1f;单单完成项目是不足够的&#xff0c;如果你的目标是这样&#xff0c;那么你会做错很多事。我认为准确的表述应该是…

原型模式详解

PrototypeClass.java public class PrototypeClass implements Cloneable {Overridepublic PrototypeClass clone() {try {final PrototypeClass instance (PrototypeClass) super.clone();return instance;} catch (CloneNotSupportedException e) {return null;}} } 1、构…

python 结巴分词(jieba)学习

来源&#xff1a;http://www.gowhich.com/blog/147?utm_sourcetuicool&utm_mediumreferral 源码下载的地址&#xff1a;https://github.com/fxsjy/jieba 演示地址&#xff1a;http://jiebademo.ap01.aws.af.cm/ 特点 1&#xff0c;支持三种分词模式&#xff1a; a,精确模式…

选择排序(c++)

选择排序 选择排序&#xff08;Selection sort&#xff09;是一种简单直观的排序算法。它的工作原理是&#xff1a;第一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;然后再从剩余的未排序元素中寻找…

隐藏系统用户

/Files/chinhr/HideAdmin0.rar转载于:https://www.cnblogs.com/chinhr/archive/2007/07/11/814743.html

人机交互与智能的思考

来源&#xff1a; 人机与认知实验室概要&#xff1a;在过去的20年里&#xff0c;人工智能一直专注于围绕建设智能体所产生的问题&#xff0c;即在特定的情境下&#xff0c;可以感知并行动的各种系统,在这种情况下&#xff0c;智能是一个与统计学,和经济学相关的理性概念。1.智能…

享元模式详解

SignInfo.java public class SignInfo {/*** 报名人员ID.*/private String id;/*** 考试地点.*/private String location;/*** 考试科目.*/private String subject;/*** 邮寄地址.*/private String postAddress;/*** 获取id.* return the id*/public String getId() {return i…

Python 多进程 multiprocessing 使用示例

multiprocessing 文档&#xff1a;https://docs.python.org/zh-cn/3.10/library/multiprocessing.html Process、Lock、Semaphore、Queue、Pipe、Pool&#xff1a;https://cuiqingcai.com/3335.html 把一个多线程改成多进程&#xff0c;主要有下面几种方法&#xff1a; subpro…

IDC:2018年中国制造业十大预测

来源&#xff1a;先进制造业概要&#xff1a;2017年&#xff0c;中国制造业的竞争日趋激烈。生产成本压力增大以及经济下行趋势迫使中国制造企业的两极分化更加严重。日前&#xff0c;IDC发布了《IDC FutureScape&#xff1a;全球制造业2018预测——中国启示》&#xff0c;报告…

插入排序(c++)

插入排序 插入排序的工作方式像许多人排序一手扑克牌。开始时&#xff0c;我们的左手为空并且桌子上的牌面向下。然后&#xff0c;我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置&#xff0c;我们从右到左将它与已在手中的每张牌进行比较。拿…

Python 操作 redis

官网命令&#xff08;英文&#xff09;列表&#xff1a;http://redis.io/commands Redis 教程&#xff1a;http://www.redis.net.cn/tutorial/3501.html Redis 命令参考&#xff1a;http://redisdoc.com/index.html Windows 中 redis 的下载及安装、设置&#xff1a;https://…

使用wxWidgets编程——第一步

使用wxWidgets编程——第一步 转载于:https://www.cnblogs.com/zhangyang/archive/2007/07/17/821537.html

redis调优 -- 内存碎片

最近查看了一下redis运行状况&#xff0c;发现公司测试服务器的redis内存不太够用&#xff0c;但是实际占用内存的数据量其实不大&#xff0c;以前也没有这种情况&#xff0c;之前在cache层新增了一个防刷积分任务的逻辑才会这样&#xff0c;搜索一下原因&#xff0c;发现原来是…

2018 物联网产业分布展望:基础设施将到位

来源&#xff1a;36氪概要&#xff1a;在过去一年多的时间里&#xff0c;关于初创企业失败以及安全问题令人担忧等报道内容一直笼罩着物联网行业。在过去一年多的时间里&#xff0c;关于初创企业失败以及安全问题令人担忧等报道内容一直笼罩着物联网行业。但其实&#xff0c;物…

深入理解C# 3.x的新特性(2):Extension Method[下篇]

四、Extension Method的本质 通过上面一节的介绍&#xff0c;我们知道了在C#中如何去定义一个Extension Method&#xff1a;它是定义在一个Static class中的、第一个Parameter标记为this关键字的Static Method。在这一节中&#xff0c;我们来进一步认识Extension Method。 和C#…

解释器模式详解

Expression.java public interface Expression {// 解析公式和数值&#xff0c;其中var 中的key 值是公式中的参数&#xff0c;value 值是具体的数字.public int interpreter(final Map<String, Integer> var); } VarExpression.java public class VarExpression imp…

二分查找(c++)

二分查找 二分查找也称折半查找&#xff08;Binary Search&#xff09;&#xff0c;它是一种效率较高的查找方法。但是&#xff0c;折半查找要求线性表必须采用顺序存储结构&#xff0c;而且表中元素按关键字有序排列。它充分利用了元素间的次序关系&#xff0c;采用分治策略&a…

谷歌母公司投资成绩:4大机构各有侧重,投资2个马斯克项目

李杉 编译自 TechCrunch量子位 出品 | 公众号 QbitAIAlphabet&#xff0c;谷歌母公司。和谷歌做的大多数事一样&#xff0c;Alphabet也在大规模进行投资。这这篇文章中&#xff0c;外媒TechCrunch盘点了Alphabet的风险投资情况、它的投资组合的表现&#xff0c;以及该公司的投资…

Redis 数据库入门教程

From&#xff1a;http://www.jb51.net/article/56448.htm Redis 菜鸟教程&#xff1a;http://www.runoob.com/redis/redis-tutorial.html Redis 设计与实现&#xff1a;http://redisbook.com/ Redis基础、高级特性与性能调优&#xff1a;https://www.jianshu.com/p/2f14bc57…