对于Python中@property的理解和使用

重看狗书,看到对User表定义的时候有下面两行

    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

遂重温下这个property的使用

在我们定义数据库字段类的时候,往往需要对其中的类属性做一些限制,一般用get和set方法来写,那在python中,我们该怎么做能够少写代码,又能优雅的实现想要的限制,减少错误的发生呢,这时候就需要我们的@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(9999)啊,直接写s.score = 9999不是更快么,加了方法做限制不能让调用的时候变麻烦啊,@property快来帮忙….

class Student(object):

    @property
    def score(self):
        return self._score

    @score.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

看上面代码可知,把get方法变为属性只需要加上@property装饰器即可,此时@property本身又会创建另外一个装饰器@score.setter,负责把set方法变成给属性赋值,这么做完后,我们调用起来既可控又方便

>>> 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!
  • 104
    点赞
  • 258
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Pythonproperty是一种特殊的装饰器,可以将方法转换为属性,让代码更加简洁和易于维护。下面,我来给你一个详细的介绍和案例。 首先,我们来看一下什么是属性。在Python,属性是对象的某些特征或状态。例如,一个人有年龄、身高和体重等属性。在面向对象编程,属性通常通过方法来访问和修改。 下面,我们来看一个简单的例子,使用属性来访问和修改一个人的年龄: ```python class Person: def __init__(self, age): self._age = age def get_age(self): return self._age def set_age(self, value): if not isinstance(value, int): raise ValueError("Age must be an integer.") if value < 0: raise ValueError("Age cannot be negative.") self._age = value age = property(get_age, set_age) ``` 在这个例子,我们定义了一个Person类,它有一个私有属性_age和一个公共属性age。公共属性age使用property装饰器将get_age和set_age方法转换为属性,从而允许我们像访问属性一样访问和修改年龄。 现在,我们可以使用这个类来创建一个人,并访问和修改它的年龄: ```python p = Person(20) print(p.age) # 输出20 p.age = 30 print(p.age) # 输出30 ``` 在这个例子,我们使用p.age来访问和修改p的年龄,而不是调用get_age和set_age方法。 除了使用property装饰器来定义属性外,我们还可以使用@property、@<属性名>.setter和@<属性名>.deleter三个装饰器来定义只读属性、只写属性和可读写属性。下面,我来给你一个例子,演示如何使用这三个装饰器: ```python class Circle: def __init__(self, radius): self._radius = radius @property def radius(self): return self._radius @radius.setter def radius(self, value): if not isinstance(value, (int, float)): raise ValueError("Radius must be a number.") if value < 0: raise ValueError("Radius cannot be negative.") self._radius = value @property def area(self): return 3.14 * self._radius ** 2 ``` 在这个例子,我们定义了一个Circle类,它有一个私有属性_radius和三个公共属性:radius、area和diameter。属性radius使用@property装饰器定义为可读写属性,属性area使用@property装饰器定义为只读属性,属性diameter使用@radius.setter装饰器定义为只写属性。 现在,我们可以使用这个类来创建一个圆,并访问和修改它的半径: ```python c = Circle(5) print(c.radius) # 输出5 print(c.area) # 输出78.5 c.radius = 10 print(c.radius) # 输出10 print(c.area) # 输出314.0 ``` 在这个例子,我们使用c.radius来访问和修改c的半径,使用c.area来访问c的面积。属性diameter没有定义getter方法,所以它是只写属性,不能用来访问半径和面积。 这就是Python属性property的详细介绍和案例。希望这篇文章能帮助你更好地理解使用属性。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值