【python基础】装饰器@property

装饰器详解中介绍了装饰器的基本用法,而python语言中内置了一些装饰器,本文介绍在类的方法定义中常用的装饰器: @property。property本质上是装饰器类,顾名思义用于属性的提取,其可将方法装饰成属性。

下面为一个用@property进行装饰的典型例子,实例方法name()在装饰后可直接通过.name进行调用(或者更严格的说法:属性取值)。property类除了提供了__get__方法(即@property的底层函数),还提供了__set____del__函数,因此可以通过同名函数的fun.setterfun.deleter分别进行属性的重新赋值和属性的删除。

class Student(object):
    def __init__(self, name, age):
        self._name = name   # 这里也可写成self.name=name
        self._age = age		# 这里也可写成self.age = age

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

	@name.deleter
    def name(self, name):
        del self._name


if __name__ == '__main__':
    s1 = Student('Mia', 18)
    print(s1.name)    # Mia
    print(s1._name)   # Mia
    s1.name = 'Lee'
    print(s1.name)  # Lee

在利用@property进行方法装饰时,要特别留意一种错误:递归调用陷阱
如在下面的例子里,其唯一的区别为在setter中定义的为self.name=name,而非成员变量self._name,此时会循环调用装饰后对应的name对象,从而导致错误。

class Student(object):
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self.name = name


if __name__ == '__main__':
    s1 = Student('Mia', 18)
    print(s1.name)      # Mia
    print(s1._name)   # Mia
    s1.name = 'Lee'       # RecursionError: maximum recursion depth exceeded
    print(s1.name)      

直观上看,采用@property装饰器对函数进行装饰有如下好处:
(1)将函数属性化;
(2)隐藏内部变量名称,从而保护代码;
(3)实现了对统一变量取值(get)、赋值(set)和删除(delete)的统一化。

除此之外,@property装饰器最大的意义在于其对于多态的支持,即相同接口下不同的类,有的直接用变量实现,有的可以间接计算出来,有的可以在赋值时增加额外的动作等等,但通过@property可以对外提供一致的接口。

【Reference】

  1. @property中的递归调用
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值