Python的@property使用方法详解

博客介绍了将类方法转换为类属性的作用、实现方式及举例。作用是可用对象直接获取属性值或赋值,实现方式有property类和装饰器,多数用装饰器。通过学生成绩表举例,解释了@property装饰器的原理,还探讨了不在__init__中设置属性的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

作用:

将类方法转换为类属性,可以用  对象 .  直接获取属性值或者对属性进行赋值

实现方式:

使用property类来实现,也可以使用property装饰器实现,二者本质是一样的。多数情况下用装饰器实现。

举例:

比如一个学生成绩表定义成这样:

class Student(object):
        def get_score(self):
            return self._score
    
        def set_score(self, value):
            if not isinstance(value, int):
                raise ValueError('score must be an integer!')
            if value < 0 or value > 100:
                raise ValueError('score must between 0 ~ 100!')
            self._score = value

我们调用的时候需要这么调用:

>>> s = Student()
    >>> s.set_score(60) # ok!
    >>> s.get_score()
    60
    >>> s.set_score(9999)
    Traceback (most recent call last):
      ...
    ValueError: score must between 0 ~ 100!

但是为了方便,们不想写s.set_score(60)啊,直接像类方法赋值那样s.score = 9999不是更快么,加了方法做限制不能让调用的时候变麻烦啊,@property快来帮忙….

   class Student(object):
        @property
        def score(self):
            return self._score
    
        @score.setter      #相当于setter方法,setter装饰器的写法是刚刚被property的装饰器所装饰的函数的名称,再加上setter属性。
        def score(self,value):
            if not isinstance(value, int):
                raise ValueError('分数必须是整数才行呐')
            if value < 0 or value > 100:
                raise ValueError('分数必须0-100之间')
            self._score = value


我们调用的时候需要这么调用:

    >>> s = Student()
    >>> s.score = 60 # OK,实际转化为s.set_score(60)
    >>> s.score # OK,实际转化为s.get_score()
    60
    >>> s.score = 9999
    Traceback (most recent call last):
      ...
    ValueError: score must between 0 ~ 100!


一开始可能不太容易理解,score明明是一个实例方法,内部也没有setter这个属性,为什么就变成了一个装饰器,还有setter这个属性了?

实际上,score()方法上增加@property装饰器,等同于score= property(fget=score),将score赋值为property的实例。

所以,被装饰后的score,已经不是这个实例方法score了,而是property的实例score。

可以将score的type打印出来看看,会得到<class 'property'>,说明score已经不是当初那个score了,他们只是同名而已。

property的另外两个方法getter、deleter也是同理。

还有一个疑惑:

为什么不直接在__init__中用self.score=score或者self.score=self.score()设置并限制对象属性呢,后来想了想,普通的类中的可以这个做,但是在模型类中就不适合这么做了,所以它的存在还是有它的道理 的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值