zoukankan      html  css  js  c++  java
  • 手动实现property装饰器

    首先,property装饰器是通过数据描述符实现的。用法很简单,大家应该都知道,这里就不细说了。

    这里主要分析一下property是如何通过描述符实现的。

    class Property:
        def __init__(self, fget):
            self.fget = fget    # 为实例增加方法,这里的方法是未绑定实例的,不会自动传入实例self
            self.fset = None    # 同上,未绑定实例
    
        def __get__(self, instance, owner):
            if instance is not None:
                return self.fget(instance)  # 调用原方法,传入实例self
            return self
    
        def __set__(self, instance, value):
            self.fset(instance, value)  # 调用原方法,传入实例self和value
    
        def setter(self, func):
            self.fset = func  # 更新属性
            return self
    
    class A:
        def __init__(self, data):
            self._data = data
    
        @Property  # data = Property(data) 描述符实例
        def data(self):
            return self._data
    
        @data.setter  # data = data.setter(data) 更新属性,并返回描述符实例
        def data(self, value):
            self._data = value
    

    访问

    a = A(100)
    print(a.data)  # 访问描述符实例,调用__get__()方法
    # 100
    
    执行过程如下:
    1. 在装饰器中,data变量指向Property(func)描述符实例
    2. 原data()函数被赋值给fget变量
    3. a.data就是访问描述符实例,触发调用__get__()方法
    4. 最后,调用fget()也就是原data()方法,并传入owner class的实例,亦即调用data(self)
    

    赋值

    a.data = 200  # 访问描述符实例,调用__set__()方法
    print(a.data)  # 访问描述符实例,调用__get__()方法
    # 200
    
    执行过程如下:
    1. 在装饰器中,data变量指向data.setter(func)描述符实例。注意,后面的data是__get__()方法返回的描述符实例
    2. 原data()函数被赋值给fset变量
    3. 赋值操作触发调用__set__方法
    4. 最后,调用fset也就是原data()方法,并传入owner class的实例和要赋的值,亦即调用data(self, value)
    

    这里涉及到装饰器,需要对装饰器和面向对象有足够的了解才能弄明白当中的变量传递,希望你不会被挡住。

    参考:
    https://docs.python.org/3/library/functions.html#property

  • 相关阅读:
    Nhibernate对应关系参数介绍
    jquery mobile 登陆后页面验证
    jquery mobile radio,checkbox button 样式设置
    jquery mobile button样式设置
    Ext 三级联动 及附值
    store操作
    Javascript中try finally的细微差别
    mysql entity framework生成画面崩溃
    PYTHON推导生成
    PYTHON修饰器
  • 原文地址:https://www.cnblogs.com/keithtt/p/10223260.html
Copyright © 2011-2022 走看看