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


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

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

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

    开始

    使用属性函数的最简单的方法之一是将它作为一个方法的装饰器来使用。这可以让你将一个类方法转变成一个类属性。

    当我需要做某些值的合并时,我发现这很有用。其他想要获取它作为方法使用的人,发现在写转换函数时它很有用。

    让我们来看一个简单的例子:

     1 ########################################################################
     2 class Person(object):
     3     """"""
     4  
     5     #----------------------------------------------------------------------
     6     def __init__(self, first_name, last_name):
     7         """Constructor"""
     8         self.first_name = first_name
     9         self.last_name = last_name
    10  
    11     #----------------------------------------------------------------------
    12     @property
    13     def full_name(self):
    14         """
    15         Return the full name
    16         """
    17         return "%s %s" % (self.first_name, self.last_name)

    在上面的代码中,我们创建了两个类属性:self.first_nameself.last_name。接下来,

    我们创建了一个full_name方法,它有一个@property装饰器。

    这使我们能够在Python解释器会话中有如下的交互:

    1 >>> person = Person("Mike", "Driscoll")
    2 >>> person.full_name
    3 'Mike Driscoll'
    4 >>> person.first_name
    5 'Mike'
    6 >>> person.full_name = "Jackalope"
    7 Traceback (most recent call last):
    8   File "<string>", line 1, in <fragment>
    9 AttributeError: can't set attribute

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

    使用Python property取代setter和getter方法

    如果你想添加可以使用正常点符号访问的属性,而不破坏所有依赖于这段代码的应用程序,

    你可以通过添加一个属性函数非常简单地改变它:

     1 from decimal import Decimal
     2  
     3 ########################################################################
     4 class Fees(object):
     5     """"""
     6  
     7     #----------------------------------------------------------------------
     8     def __init__(self):
     9         """Constructor"""
    10         self._fee = None
    11  
    12     #----------------------------------------------------------------------
    13     def get_fee(self):
    14         """
    15         Return the current fee
    16         """
    17         return self._fee
    18  
    19     #----------------------------------------------------------------------
    20     def set_fee(self, value):
    21         """
    22         Set the fee
    23         """
    24         if isinstance(value, str):
    25             self._fee = Decimal(value)
    26         elif isinstance(value, Decimal):
    27             self._fee = value
    28  
    29     fee = property(get_fee, set_fee)

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

    1 >>> f = Fees()
    2 >>> f.set_fee("1")
    3 >>> f.fee
    4 Decimal('1')
    5 >>> f.fee = "2"
    6 >>> f.get_fee()
    7 Decimal('2')

    正如你所看到的,当我们以这种方式使用属性函数时,它允许fee属性设置并获取值本身而不破坏原有代码。

    让我们使用属性装饰器来重写这段代码,看看我们是否能得到一个允许设置的属性值。

     1 from decimal import Decimal
     2  
     3 ########################################################################
     4 class Fees(object):
     5     """"""
     6  
     7     #----------------------------------------------------------------------
     8     def __init__(self):
     9         """Constructor"""
    10         self._fee = None
    11  
    12     #----------------------------------------------------------------------
    13     @property
    14     def fee(self):
    15         """
    16         The fee property - the getter
    17         """
    18         return self._fee
    19  
    20     #----------------------------------------------------------------------
    21     @fee.setter
    22     def fee(self, value):
    23         """
    24         The setter of the fee property
    25         """
    26         if isinstance(value, str):
    27             self._fee = Decimal(value)
    28         elif isinstance(value, Decimal):
    29             self._fee = value
    30  
    31 #----------------------------------------------------------------------
    32 if __name__ == "__main__":
    33     f = Fees()

    上面的代码演示了如何为fee属性创建一个setter方法。你可以用一个名为@fee.setter的装

    饰器装饰第二个方法名也为fee的方法来实现这个。当你如下所做时,setter被调用:

    1 >>> f = Fees()
    2 >>> f.fee = "1"

    如果你看属性函数的说明,它有fget, fset, fdel和doc几个参数。如果你想对属性使用del命令,

    你可以使用@fee.deleter创建另一个装饰器来装饰相同名字的函数从而实现删除的同样效果。

    补充阅读:

  • 相关阅读:
    容器跨主机网络通信学习笔记(以Flannel为例)
    Kubernetes控制器Job和CronJob
    记一次使用Flannel插件排错历程
    Kubernetes控制器Deployment
    Kubernetes如何通过StatefulSet支持有状态应用?
    react18 来了,我 get 到...
    gojs 实用高级用法
    vuecli3 vue2 保留 webpack 支持 vite 成功实践
    calibre 报错 This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. 解决
    unable to recognize "*.yaml": no matches for kind "RoleBinding" in version "rbac.authorization.k8s.io/v1beta1"
  • 原文地址:https://www.cnblogs.com/MrFiona/p/7120379.html
Copyright © 2020-2023  润新知