Python进阶之“属性(property)”详解
admin
2023-07-31 01:43:24
0

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

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

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

开始

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

1234567891011121314151617 ########################################################################class Person(object):    \”\”\”\”\”\”     #———————————————————————-    def __init__(self, first_name, last_name):        \”\”\”Constructor\”\”\”        self.first_name = first_name        self.last_name = last_name     #———————————————————————-    @property    def 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解释器会话中有如下的交互:

123456789 >>> person = Person(\”Mike\”, \”Driscoll\”)>>> person.full_name\’Mike Driscoll\’>>> person.first_name\’Mike\’>>> person.full_name = \”Jackalope\”Traceback (most recent call last):  File \”\”, line 1, in <fragment>AttributeError: can\’t set attribute

正如你所看到的,因为我们将方法变成了属性,我们可以使用正常的点符号访问它。但是,如果我们试图将该属性设为其他值,我们会引发一个AttributeError错误。改变full_name属性的唯一方法是间接这样做:

123 >>> person.first_name = \”Dan\”>>> person.full_name\’Dan Driscoll\’

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

使用Python property取代setter和getter方法

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

123456789101112131415161718192021222324252627 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方法​​:

1234 >>> f = Fees()>>> f.set_fee(\”1\”)>>> f.get_fee()Decimal(\’1\’)

如果你想添加可以使用正常点符号访问的属性,而不破坏所有依赖于这段代码的应用程序,你可以通过添加一个属性函数非常简单地改变它:

1234567891011121314151617181920212223242526272829 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     fee = property(get_fee, set_fee)

我们在这段代码的末尾添加了一行。现在我们可以这样做:

1234567 >>> f = Fees()>>> f.set_fee(\”1\”)>>> f.feeDecimal(\’1\’)>>> f.fee = \”2\”>>> f.get_fee()Decimal(\’2\’)

正如你所看到的,当我们以这种方式使用属性函数时,它允许fee属性设置并获取值本身而不破坏原有代码。让我们使用属性装饰器来重写这段代码,看看我们是否能得到一个允许设置的属性值。

123456789101112131415161718192021222324252627282930313233 from decimal import Decimal ########################################################################class Fees(object):    \”\”\”\”\”\”     #———————————————————————-    def __init__(self):        \”\”\”Constructor\”\”\”        self._fee = None     #———————————————————————-    @property    def fee(self):        \”\”\”        The fee property – the getter        \”\”\”        return self._fee     #———————————————————————-    @fee.setter    def fee(self, value):        \”\”\”        The setter of the fee property        \”\”\”        if isinstance(value, str):            self._fee = Decimal(value)        elif isinstance(

相关内容

热门资讯

500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
Prometheus+Graf... 一,Prometheus概述 1,什么是Prometheus?Prometheus是最初在Sound...
python绘图库Matplo... 本文简单介绍了Python绘图库Matplotlib的安装,简介如下: matplotlib是pyt...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...