Python中@property和@*.setter装饰器的详细用法

有这么个场景:

class result:
    def __init__(self):
        self.data = [11,33,44,55,66]

exam_result = result()
exam_result.data = 1

exam_result.data 可以被随意修改,可我只希望它是一个只读属性,应该怎么做呢?

@property

@property装饰器的作用是,将一个函数装饰成为类的一个属性,当某个属性需要动态的计算时,用@property来装饰函数最好不过了;

了解@函数修饰符的人应该知道property实际上是一个函数。

使用方法:

class result:
    def __init__(self):
        self.__data = [11,33,44,55,66]

    @property
    def data(self):
        return self.__data

这时候再对 exam_result.data进行赋值,就会发生AttributeError: can’t set attribute的错误!

这时候data不仅是一个方法,还是类的一个属性,所以我们可以利用这个特性动态的计算某些结果:

    @property
    def total(self):
        total_ = 0
        for value in self.__data:
            total_ += value
        return total_

为result类添加一个新的值total用于计算总分数。

修改代码,实现一个新的功能,获取分数及格的总数;

        self.__pass_score = 60

添加一个 __pass_score的属性,用于记录及格分数线,暂且初始化为60;

    @property
    def passCount(self):
        count = 0
        for value in self.__data:
            if value >= self.__pass_score:
                count+=1
        return count

添加一个passCount函数,用于获取及格的数量。使用@property修饰。

现在我希望能够设置及格分数线,并要保证其值合法;

@*.setter

@*.setter 允许你对已用@property装饰的函数赋值:

    @passScore.setter
    def passScore(self,value):
        if not 0 < value < 100:
            raise ValueError('必须为1~99的数')
        self.__pass_score=value

需要注意,setter装饰器必须在property的后面,且两个被修饰的属性(函数)名称必须保持一致。

因为属性实际是通过函数执行获得,所以我们可以对值进行判断或实现更为复杂的操作。

完整代码:

class result:
    def __init__(self):
        self.__data = [11,33,44,55,66]
        self.__pass_score = 60
    @property
    def data(self):
        return self.__data
    
    @property
    def total(self):
        total_ = 0
        for value in self.__data:
            total_ += value
        return total_
    @property
    def passCount(self):
        count = 0
        for value in self.__data:
            if value >= self.__pass_score:
                count+=1
        return count
    @property
    def passScore(self):
        return self.__pass_score
    @passScore.setter
    def passScore(self,value):
        if not 0 < value < 100:
            raise ValueError('必须为1~99的数')
        self.__pass_score=value

原创内容,如需转载,请注明出处;

本文地址: https://www.perfcode.com/p/966.html

分类: 计算机技术
推荐阅读:
Python slice()函数 在 Python 中,slice() 函数用于创建一个 slice 对象,该对象可以用于对序列进行切片操作。slice() 函数接受三个参数:起始位置、结束位置和步长。这些参数都是可选的。
Rust option_env宏的用法和示例 option_env宏是Rust语言中的一个标准宏,用于在编译阶段从环境变量中获取值;它将扩展成一个Option<&'static str>类型的值,如果指定的环境变量在编译时存在,值为Some(value),否则为None。
cannot fallthrough final case in switch的解决方法 在Go语言中,fallthrough 用于 switch 语句的 case 块中,它将会在当前 case 块执行完后执行下一个 case 块,不论下个 case 块条件是否匹配,但如果 fallthrough 后没有 case ,则会产生 cannot fallthrough final case in switch 的错误。
Golang中imported and not used:这类错误解决办法 在Golang中,比较容易碰到诸如 imported and not used: "time" 这样的错误;在这里表示你导入了一个time包却没有使用它;
未定义标识符 CV_BayerGR2BGR 解决方法 CV_BayerGR2BGR 是 OpenCV 中的颜色转换常量,值为49,在文件 opencv2/imgproc/types_c.h 中定义;提示未定义标识符CV_BayerGR2BGR是因为没有引入opencv2/imgproc/types_c.h这个头文件;
Pyside6.QtWidgets.QApplication详细教程 PySide6.QtWidgets.QApplication类用于管理GUI应用程序的控制流和主要设置;