Python——类属性装饰器property的实现(数据描述器)

class Property:
    def __init__(self,fget=None, fset=None, fdel=None):
        self._fget = fget
        self._fset = fset
        self._fdel = fdel

    # 这是实例调用的装饰器@obj.setter
    def setter(self, fn=None):
        print("Property setter", fn)
        self._fset = fn
        return self

    # 这是实例调用的装饰器@obj.deleter
    def deleter(self, fn=None):
        print("Property deleter",fn)
        self._fdel = fn
        return self

    # obj.name 中的 . 将触发 这个方法
    def __get__(self, instance, owner):
        return self._fget(instance)

    # obj.name = value  中的 = 触发 __set__
    def __set__(self, instance, value):
        self._fset(instance, value)

    # del obj.name  del触发 __delete
    def __delete__(self, instance):
        # 描述器初始化,del触发__delete__(),然后再 来 调用对应的属性方法
        self._fdel(instance)

# 测试类
class Test:
    def __init__(self, age=18):
        self.__age = age
        self._city = 'beijing'

    @Property  # city = Property(city) ,这里触发的是装饰的__init__(),相当于是一个建立一个类属性的Propery实例对象,也就是描述器
    def city(self):
        return self._city

    @city.setter  # 这里触发的是装饰的 setter()方法,装饰器是需要返回一个值的
    def city(self, city):
        self._city = city

    @city.deleter # city = city.deleter(city) => Property(city).deleter(city)
    def city(self):
        print("Property delete city:{}".format(self._city))

    def get_age(self):
        return self.__age

    def set_age(self, age):
        self.__age = age

    def del_age(self):
        print('Property delete age:{}'.format(self.__age))

    age = Property(get_age, set_age, del_age)

# ===========================

t = Test()

# 属性装饰器测试---> city
print(getattr(t, "_Test__age"), getattr(t, '_city'))
print("=-+"*20)
print(t.__dict__)
print(t.city)
t.city = "shanghai"
print(t.__dict__)
print(t.city)
del t.city

# 属性装饰器测试---> city
print("=-+"*20)
print(t.age)
t.age = 29
print(t.age)
print(t.__dict__)
del t.age

【执行结果】

Property setter <function Test.city at 0x0000000000D80E18>
Property deleter <function Test.city at 0x0000000000D80EA0>
18 beijing
=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+
{'_Test__age': 18, '_city': 'beijing'}
beijing
{'_Test__age': 18, '_city': 'shanghai'}
shanghai
Property delete city:shanghai
=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+=-+
18
29
{'_Test__age': 29, '_city': 'shanghai'}
Property delete age:29

【程序执行总结】

编译运行后,

先初始化 类中装饰包装的类方法,构建包装的新方法。

同时绑定了类变量的装饰器实例化对象,也就构建了数据描述器。

当运行到实例属性的类同名属性的相关操作时,触发描述器的相关方法,

obj.name               =>       __get__() 

obj.name = value  =>       __set__() 

del obj.name         =>      __delete__()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值