• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    详解Python装饰器之@property

    一、property() 函数讲解

    了解 @property 装饰器之前,我们首先要了解内置函数的 property()。

    class property(fget=None, fset=None, fdel=None, doc=None)

    描述:

    参数说明:

    返回值:

    注意:

    在 3.5 版更改:特征属性对象的文档字符串现在是可写的。

    首先我们要知道 property() 函数是用来干什么的?

    托管的哪些东西呢?

    在类外使用托管属性和直接使用指定的属性有什么区别呢?

    示例:一个典型的用法是定义一个托管属性 x。

    class C:
        def __init__(self):
            self._x = None
     
        def getx(self):          # 定义一个方法 getx() 用来访问 _x
            return self._x
     
        def setx(self, value):   # 定义一个方法 setx() 用来设置 _x
            self._x = value
     
        def delx(self):          # 定义一个方法 delx() 用来删除 _x
            del self._x
            print("完成 _x 或 x 的删除!")
     
        x = property(getx, setx, delx, "x 是一个托管属性")     # 根据 property() 函数的特点创建一个托管属性 x
     
     
    c = C()                # 创建一个实例对象 c
    c.x = "王大头"         # 实例调用托管属性 x,对 x 赋值就是调用 setx() 方法
    print(c.x)             # 实例调用托管属性 x,打印 x 就是调用 getx() 方法
    print(C.x.__doc__)     # 类调用托管属性 x,调用 __doc__ 打印 x 的文档字符串
    del c.x                # 删除托管属性 x,就是调用 delx() 方法
    

    运行结果:

    王大头
    x 是一个托管属性
    完成 _x 或 x 的删除!

    二、@property 装饰器讲解

    首先我们定义一个 C 类,在类中定义一个实例属性 score。

    如果我们要访问或修改属性 score 时,可以直接在类外通过类的实例进行。如下:

    class C:
        def __init__(self):
            self.score = 85          # 默认分数为 85
     
     
    c = C()                          # 创建一个 C 类的实例 c
    print(c.score)                   # 通过 C 类的实例对象 c,调用 score 属性来实现访问
    c.score = 60                     # 通过 C 类的实例对象 c 直接修改属性 score
    print(c.score)
    

    运行结果:

    85
    60

    我们发现普通的属性访问、修改、删除这样做是可以的,但是如果我们要在访问、修改、删除时增加过滤条件,那么这样操作显然是不行的。

    我们还可以通过在类中定义的方法,在方法中添加过滤条件来实现属性的访问、修改、删除。在类外需要通过实例调用对应方法来实现,如下:

    class C:
        def __init__(self):
            self.score = 85
     
        def get_score(self):                 # 定义一个方法 get_score() 用来获取分数
            if self.score  60:
                return "你妹的,不及格!"
            else:
                return self.score
     
        def set_score(self, value):          # 定义一个方法 set_score() 用来输入分数
            if 0 = value = 100:
                self.score = value
            else:
                print(f"输入的值 {value} 超出范围 0~100 !")
     
        def del_score(self):                 # 定义一个方法 del_score() 用来删除分数
            del self.score
            print("完成 score 属性的删除!")
     
     
    c = C()
    c.set_score(99)               # 通过实例对象调用 set_score() 方法来实现 score 属性的赋值或修改
    print(c.get_score())          # 通过实例对象调用 get_score() 方法来实现 score 属性的访问
    c.del_score()                 # 通过实例对象调用 del_score() 方法来实现 score 属性的删除
    

    运行结果:

    99
    完成 score 属性的删除!

    通过上节对 property() 了解,我们发现 property() 函数的参数 fget、fset、fdel 分别对应着 获取属性函数、设置属性函数 和 删除属性函数。如此以来我们就可以将 score 属性通过 property() 函数委托给 score_x,将 get_score()、set_score()、del_score() 方法分别传递给 fget、fset、fdel 参数。利用托管属性 score_x,我们可以以最简单的方式对属性实现有过滤条件访问、赋值、删除。如下:

    class C:
        def __init__(self):
            self.score = 85
     
        def get_score(self):
            if self.score  60:
                return "你妹的,不及格!"
            else:
                return self.score
     
        def set_score(self, value):
            if 0 = value = 100:
                self.score = value
            else:
                print(f"输入的值 {value} 超出范围 0~100 !")
     
        def del_score(self):
            del self.score
            print("完成 score 属性的删除!")
     
        score_x = property(fget=get_score, fset=set_score, fdel=del_score, doc="score_x 是 score 的托管属性。")
     
     
    c = C()
    c.score_x = 45          # 直接使用实例对象调用 score_x 进行赋值,背后还是调用了方法实现了过滤
    print(c.score_x)        # 获取 score_x 的值
    del c.score_x           # 删除 score
    

    运行结果:

    你妹的,不及格!
    完成 score 属性的删除

    我们再来看看 property() 作为 装饰器 decorator 来使用,@property 装饰器是将被装饰的方法转化为一个同名的只读的特征属性,被装饰方法的文档字符串就是装饰后同名属性的文档字符串:

    class C:
        def __init__(self):
            self.score = 85
     
        @property
        def score_x(self):
            """score_x 就相当于一个 score 的托管属性。"""
            return self.score
     
     
    c = C()
    print(c.score_x)                  # score_x() 方法被转换为属性后,该属性的值就是方法的返回值
    print(C.score_x.__doc__)          # 查看该属性的字符串文档
    c.score_x = 90                    # 对 score_x 属性的修改失败,因为它是个只读属性
    

    运行结果:


    85
    score_x 就相当于一个 score 的托管属性。
    Traceback (most recent call last):
      File "C:\Users\13160\Desktop\Python Exercise\011.py", line 14, in module>
        c.score_x = 90
    AttributeError: can't set attribute

    我们发现这样使用 @property 装饰器装饰的方法,只是转变为了只读属性,不能修改也不能删除。这似乎好像与 property() 函数创建托管属性既可以访问又可以修改、删除有些不同。

    我们要知道 @property 装饰器的本质是 property() 函数,所以被装饰的方法就相当于 property() 函数创建的托管属性。托管属性对象是具有相应的属性 fget,fset 和 fdel(访问、设置、删除),而被 @property 装饰器装饰的对象同样也具有对应的 getter,setter 以及 deleter 方法。所以要想被 @property 装饰器装饰的函数转换为属性后也可以实现设置、删除操作,可以做如下设置:

    class C:
        def __init__(self):
            self.score = 85
     
        @property                           # @property 装饰器本身就相当于 getter 方法
        def score_x(self):
            if self.score  60:
                return "你妹的,不及格!"
            else:
                return self.score
     
        @score_x.setter                     # 给 score_x 属性装饰 setter 方法
        def score_x(self, value):           # 附加方法与原始的特征属性相同的名称
            if 0 = value = 100:
                self.score = value
            else:
                print(f"输入的值 {value} 超出范围 0~100 !")
     
        @score_x.deleter                    # 给 score_x 属性装饰 deleter 方法
        def score_x(self):                  # 附加方法与原始的特征属性相同的名称
            del self.score
     
     
    c = C()
    print(c.score_x)
    c.score_x = 45
    print(c.score_x)
    

    运行结果:

    85
    你妹的,不及格!

    通过上面 @property 装饰器的应用我们可以看出,它和直接使用 property() 函数创建委托属性其实没啥区别。

    注意:

    到此这篇关于详解Python装饰器之@property的文章就介绍到这了,更多相关Python @property内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • Python的@property的使用
    • python property的使用技巧分享
    • python中关于property的最详细使用方法
    • python中@property的作用和getter setter的解释
    • Python中关于property使用的小技巧
    上一篇:python 中sys.getsizeof的用法说明
    下一篇:python子线程如何有序执行
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    详解Python装饰器之@property 详解,Python,装饰,器之,@property,